Spring的应用主要集中在Ioc/AOP/DAO/事务四个方面。Spring事务是非常重要的一部分。
一、事务控制的基本知识
事务的概念:
事务是一组原子性操作的工作单元,这组工作单元要么执行成功,要么不成功。
事务有四个属性:
原子性、一致性、独立性和持久性(CAID),所有这些方面都是依靠事务资源去维护。
事务隔离:
SQL 标准用三个必须在并行的事务之间避免的现象定义了四个级别的事务隔离。
三个不希望发生的现象是:
脏读(dirty reads):
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
读未提交(Read uncommitted) | 可能 | 可能 | 可能 |
读已提交(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
二、从编程的角度理解事务
和数据库事务概念几乎完全一样:事务是一种机制,把组成的多个操作视为一个操作单元进行处理,这个单元要么全部执行成功,要么全部不执行。在事务中,涉及的操作可能依赖于很多不同的数据库和服务器。
从程序角度考虑,事务可以分为两大类:一种是本地事务,一种是全局事务(也叫分布式事务)。
事务源:是可以绑定事务操作的资源。事务的概念最初来自数据库的操作,事务的资源也仅限于数据库。但编程中的事务,事务源很广泛,不但可以包含数据库,还可以包含打印机等。
三、认识Spring的事务包的API
Spring对事务的控制的API全部位于org.springframework.transaction包下面,其中除去异常定义的类外,仅有四个接口,这四个接口是Spring操作事务的核心,下面一一介绍:
包:
org.springframework.transaction
接口:
PlatformTransactionManager //事务管理平台
异常:
CannotCreateTransactionExceptionHeuristicCompletionExceptionIllegalTransactionStateExceptionInvalidIsolationLevelExceptionInvalidTimeoutExceptionNestedTransactionNotSupportedExceptionNoTransactionExceptionTransactionExceptionTransactionSuspensionNotSupportedExceptionTransactionSystemExceptionTransactionTimedOutExceptionTransactionUsageExceptionUnexpectedRollbackException
要搞明白Spring事务控制的原理,必须理解上面四个接口的含义,下面一一介绍之。
1、PlatformTransactionManager
是一个事务管理平台,该接口有许多具体的事务实现类,例如DataSourceTransactionManager, HibernateTransactionManager, JdoTransactionManager, JmsTransactionManager, JpaTransactionManager, JtaTransactionManager, TopLinkTransactionManager, WebLogicJtaTransactionManager 等等,通过实现此接口,Spring可以管理任何实现了这些接口的事务。开发人员也可以使用统一的编程模型来控制管理事务。此接口中有三个方法:
//Commit the given transaction, with regard to its status.
//监视事务状态,并提交一个事务
void commit(TransactionStatus status)
//Return a currently active transaction or create a new one, according to the specified propagation behavior.
//根据事务的隔离级别和传播行为,返回当前活动的事务或者产生一个新的事务。
TransactionStatus getTransaction(TransactionDefinition definition)
//Roll back the given transaction.
//回滚给定的事务
void rollback(TransactionStatus status)
//Create a new savepoint.
//创建一个新的回滚点
Object createSavepoint()
//Explicitly release the given savepoint.
//释放一个给定的回滚点
void releaseSavepoint(Object savepoint)
//Roll back to the given savepoint.
//回滚到给定的回滚点
void rollbackToSavepoint(Object savepoint)
字段摘要:(因为是接口,里面都是int常量,即public static final类型的,很多,我就只写常量的名字和含义)
//事务隔离级别(数据库级别的知识)
TransactionDefinition.ISOLATION_DEFAULT
//使用底层数据库默认隔离级别。
TransactionDefinition.ISOLATION_READ_UNCOMMITTED //读未提交
/*最低隔离等级,允许事务读取其他并行的事务还没有提交的数据,会发生脏读(dirty reads)、
不可重复读(non-repeatable reads)、幻读(phantom read)等问题。*/
TransactionDefinition.ISOLATION_READ_COMMITTED //读已提交
//允许事务读取其他并行的事务已经提交的数据,可以防止脏读问题。
TransactionDefinition.ISOLATION_REPEATABLE_READ //可重复读
//保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。
TransactionDefinition.ISOLATION_SERIALIZABLE //可串行化
//所有事务都严格隔离,各个事务顺序执行。很容易发生死锁。
TransactionDefinition.PROPAGATION_REQUIRED
支持现有的事务,如果没有则新建一个事务。
TransactionDefinition.PROPAGATION_SUPPORTS
支持现有的事务,如果没有则以非事务状态运行。
TransactionDefinition.PROPAGATION_MANDATORY
支持现有事务,如果没有则抛出异常。
TransactionDefinition.PROPAGATION_REQUIRES_NEW
总是发起一个新事务。如果当前已存在一个事务,则将其挂起。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED
不支持事务,总是以非事务状态运行,如果当前存在一个事务,则将其挂起。
TransactionDefinition.PROPAGATION_NEVER
不支持事务,总是以非事务状态运行,如果当前存在一个事务,则抛出异常。
TransactionDefinition.PROPAGATION_NESTED
如果石阡已经存在一个事务,则以嵌套事务的方式运行,如果当前没有事务,则创建一个新事务
int getIsolationLevel()
Return the isolation level.
返回事务的隔离级别。
String getName()
Return the name of this transaction.
返回事务的名字。
int getPropagationBehavior()
Return the propagation behavior.
返回事务的是传播行为。
int getTimeout()
Return the transaction timeout.
返回事务的超时时间。
boolean isReadOnly()
Return whether to optimize as read-only transaction.
返回是否(优化为)只读属性。
这个接口的作用就是获取事务的状态(回滚点、是否完成、是否新事物、是否回滚)属性,还可以进行事务rollback-only的设置。
方法摘要
boolean hasSavepoint()
Return whether this transaction internally carries a savepoint, i.e. has been created as nested
transaction based on a savepoint.
判断这个事务是否有一个内在的回滚点(savepoint),即创建为基于回滚点的嵌套事务。
boolean isCompleted()
Return whether this transaction is completed, that is, has already been committed or rolled back.
判断这个事务是否完成,也就是已经提交或者回滚。
boolean isNewTransaction()
Return if the transaction is new, else participating in an existing transaction.
判断一个事物是否为新事务,或者是这个事务参与到一个已经存在的事务里面。
boolean isRollbackOnly()
Return if the transaction has been set rollback-only.
判断这个事务是否已经设置了rollback-only。
void setRollbackOnly()
Set the transaction rollback-only.
设置这个事务rollback-only。
使用Spring编程时事务管理时,一般步骤如下:
2、定义TransactionDefinition并设置好事务的隔离级别和传播方式。
3、通过PlatformTransactionManager.getTransaction()开始一个事务,并获得TransactionStatus对象。
4、运行需要在事务环境下执行的代码并捕获异常。
5、如果有异常发生,将TransactionStatus设置为setRollbackOnly(),表示要回滚事务。
6、调用PlatformTransactionManager.commit(TransactionStatus)方法提交事务,Spring根据TransactionStatus的状态决定如何提交事务。如果TransactionStatus设置为setRollbackOnly(),则回滚事务,否则提交