Spring提供一流的事务管理,分为声明式事务和编程式事务。
1 Spring的事务
事务是一组任务组成的工作单元,执行的结果是要么全部执行,要么都不执行。
Spring事务的优点:
提供统一的编程模式 提供更简单,更易用的事务管理 支持声明事务 整合Spring对数据访问的抽象
2 事务的ACID特性
原子性:
要么事务的中的任务全部执行,要不都不执行
一致性:事务必须保证和数据库的一致性,即数据库的数据必须和现实的数据一致。
隔离性
不同的事务之间互不干扰
持久性:
如果事务执行成功,无论系统发生什么情况,事务的执行结果都是永久的
3 事务的缺陷
脏读取:
一个事务读取另一个事务尚未提交的更新
不可重复的读取:
一个事务前后两次读取数据都不一致,因为前后读取期间有另一个事务改变了数据。不可重复读读到的是更改或者是删除的数据
幻读:
A事务读取了B事务提交的新增数据,这时候A事务就会出现幻象读的问题,幻象读读到的是新增的数据
4 数据库锁的机制
根据锁定的对象不同,可以分为表锁定和行锁定,前者对整个表锁定,或者对表中的特定的行锁定。从并发事务锁定的关系上看,可以分为共享锁定和独占锁定。
行共享锁定:一般可以通过select for update来隐式来获取,也可以通过lock table in row share mode.行共享锁并不防止对数据行进行更改的操作,但是可以防止其它会话获取独占性数据表锁定。
行独占锁定:可以通过insert update delete来语句隐式来获取,可以通过lock table in row exclusive mode.这个锁定可以防止其它会话获取一个共享锁定,共享行独占锁定或独占锁定。
表共享锁定:lock table in share mode
表共享行独占:lock table in share mode row exclusive mode.
表独占:lock table in Exclusive mode,防止其它会话的所有的锁。
5 事务隔离级别
READ UNCOMMITED READ COMMITED REPEATABLE READ SERIALIZABLE
6 事务管理关键抽象
在事务管理管理SPI高层抽象层主要包括3个接口,分别是TransactionDefinition<————PlaformTransactionManager——>TransactionStatus
TransactionDefinition用于标书事务的隔离级别,超时时间,是否为只读事务和事务传播等控制事务具体行为的事务属性,这些事务属性可以通过XML配置或注解描述提供,也可以通过手工编程的方式设置。
PlatformTransactionManager根据TransactionDefinition提供的事务属性配置信息,创建事务,并用TransactionStatus描述这个激活事务的状态。
TransactionDefinition:
TransactionDefinition定义了Spring兼容性的事务属性,这些属性对事务管理控制的若干方面进行配置。
事务隔离:当前事务和其它事务的隔离的程度。在TranscationDefiniton接口中,定义了和java.sql.Connnection接口汇总同名的4个隔离级别:
ISOLATION_READ_UNCOMMITED,ISOLATION_READ_COMMITTED,ISOLATION_REPEATABLE_READ,ISOLATION_SERIALIZABLE,还有一个默认的
隔离级别:ISOLATION_DEFUALT
事务传播:通常一个事务中执行的所有代码都会运行在同一事务上下文中,但是Spring也提供了几个可选的事务传播类型,如挂起当前的事务,创建一个新的
事务。
事务超时:
事务在超时前能运行多久,超过时间后,事务会被回滚。
只读状态:
只读事务不修改任何数据,性能高。
TransactionStatus:
TransactionStatus代表一个事务的具体运行状态,事务管理器可以通过该接口来获取事务运行时期的状态信息,可以通过该接口间接地回滚事务。该接口继承于SavepointManager.
SavepintManager接口拥有一下的方法:
Object createSavepoint()
创建一个保存点对象,以便后面可以利用rollbackToSavePoint(Object savepoint)方法回滚大特定的保存点上
void rollbackToSavepoint(Object savepoint)
将事务回滚到特定的保存点上,被回滚的保存单将自动释放。
void releaseSavepoint(Object savepoint)
释放一个保存点,如果事务提交,所有的保存点都对被释放,不需要手工释放。
TransactionStatus扩展了SavepointManager提供了一下的方法:
boolean hasSavepoint():判断是否在内部创建了一个保存点。
boolean isNewTransaction():潘丹是不是一个新的事务
boolean isCompleted():判断事务是不是已经结束:已经提交或者回滚
boolean isRollbackOnly:当前事务是否已经被标志位rollback_only
void setRollbackOnly:将当前的事务设置为rollback_only.
PlatformTransactionManager:
public interface PlatformTransactionManager {
/**
* Return a currently active transaction or create a new one, according to
* the specified propagation behavior.
* <p>Note that parameters like isolation level or timeout will only be applied
* to new transactions, and thus be ignored when participating in active ones.
* <p>Furthermore, not all transaction definition settings will be supported
* by every transaction manager: A proper transaction manager implementation
* should throw an exception when unsupported settings are encountered.
* <p>An exception to the above rule is the read-only flag, which should be
* ignored if no explicit read-only mode is supported. Essentially, the
* read-only flag is just a hint for potential optimization.
* @param definition TransactionDefinition instance (can be {@code null} for defaults),
* describing propagation behavior, isolation level, timeout etc.
* @return transaction status object representing the new or current transaction
* @throws TransactionException in case of lookup, creation, or system errors
* @throws IllegalTransactionStateException if the given transaction definition
* cannot be executed (for example, if a currently active transaction is in
* conflict with the specified propagation behavior)
* @see TransactionDefinition#getPropagationBehavior
* @see TransactionDefinition#getIsolationLevel
* @see TransactionDefinition#getTimeout
* @see TransactionDefinition#isReadOnly
*/
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
/**
* Commit the given transaction, with regard to its status. If the transaction
* has been marked rollback-only programmatically, perform a rollback.
* <p>If the transaction wasn't a new one, omit the commit for proper
* participation in the surrounding transaction. If a previous transaction
* has been suspended to be able to create a new one, resume the previous
* transaction after committing the new one.
* <p>Note that when the commit call completes, no matter if normally or
* throwing an exception, the transaction must be fully completed and
* cleaned up. No rollback call should be expected in such a case.
* <p>If this method throws an exception other than a TransactionException,
* then some before-commit error caused the commit attempt to fail. For
* example, an O/R Mapping tool might have tried to flush changes to the
* database right before commit, with the resulting DataAccessException
* causing the transaction to fail. The original exception will be
* propagated to the caller of this commit method in such a case.
* @param status object returned by the {@code getTransaction} method
* @throws UnexpectedRollbackException in case of an unexpected rollback
* that the transaction coordinator initiated
* @throws HeuristicCompletionException in case of a transaction failure
* caused by a heuristic decision on the side of the transaction coordinator
* @throws TransactionSystemException in case of commit or system errors
* (typically caused by fundamental resource failures)
* @throws IllegalTransactionStateException if the given transaction
* is already completed (that is, committed or rolled back)
* @see TransactionStatus#setRollbackOnly
*/
void commit(TransactionStatus status) throws TransactionException;
/**
* Perform a rollback of the given transaction.
* <p>If the transaction wasn't a new one, just set it rollback-only for proper
* participation in the surrounding transaction. If a previous transaction
* has been suspended to be able to create a new one, resume the previous
* transaction after rolling back the new one.
* <p><b>Do not call rollback on a transaction if commit threw an exception.</b>
* The transaction will already have been completed and cleaned up when commit
* returns, even in case of a commit exception. Consequently, a rollback call
* after commit failure will lead to an IllegalTransactionStateException.
* @param status object returned by the {@code getTransaction} method
* @throws TransactionSystemException in case of rollback or system errors
* (typically caused by fundamental resource failures)
* @throws IllegalTransactionStateException if the given transaction
* is already completed (that is, committed or rolled back)
*/
void rollback(TransactionStatus status) throws TransactionException;
}
5 编程式事务管理
TransactionTemplate和那些持久化模板类一样,是线程安全的。
Object execute(TransactionCallback action) :在TransactionCallBack回调接口中定义需要以事务方式组织的数据访问逻辑。
public class Forum1Service {
private TransactionTemplate template;
public void addForum(){
template.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
//需要在事务环境中执行的代码
}
});
}
}
6 使用XML声明事务
7 使用注解声明事务