Spring的事务
- 在 xml 配置文件中添加
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
- @EnableTransactionManagement 注解也可以启用事务管理功能。
事务隔离级别
隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量:
-
TransactionDefinition.ISOLATION_DEFAULT
:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。 -
TransactionDefinition.ISOLATION_READ_UNCOMMITTED
:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别。 -
TransactionDefinition.ISOLATION_READ_COMMITTED
:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。 -
TransactionDefinition.ISOLATION_REPEATABLE_READ
:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。 -
TransactionDefinition.ISOLATION_SERIALIZABLE
:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
事务传播行为
所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
-
TransactionDefinition.PROPAGATION_REQUIRED
:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。 -
TransactionDefinition.PROPAGATION_REQUIRES_NEW
:创建一个新的事务,如果当前存在事务,则把当前事务挂起。 -
TransactionDefinition.PROPAGATION_SUPPORTS
:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 -
TransactionDefinition.PROPAGATION_NOT_SUPPORTED
:以非事务方式运行,如果当前存在事务,则把当前事务挂起。 -
TransactionDefinition.PROPAGATION_NEVER
:以非事务方式运行,如果当前存在事务,则抛出异常。 -
TransactionDefinition.PROPAGATION_MANDATORY
:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 -
TransactionDefinition.PROPAGATION_NESTED
:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
事务超时
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。
事务只读属性
只读事务用于客户代码只读但不修改数据的情形,只读事务用于特定情景下的优化,比如使用Hibernate的时候。默认为 读写事务。
@Transactional属性
属性 | 类型 | 描述 |
---|---|---|
value | String | 可选的描述符,指定使用的事务管理器 |
propagation | enum: Propagation | 可选的事务传播行为设置, 默认值TransactionDefinition.PROPAGATION_REQUIRED |
isolation | enum : Isolation | 可选的事务隔离级别设置,默认值TransactionDefinition.ISOLATION_DEFAULT,使用底层数据库的默认隔离级别 |
readOnly | boolean | 读写或只读事务,默认读写 |
timeout | int(in seconds granularity) | 事务超时时间设置 |
rollbackFor | class对象数组,必须继承自Throwable | 导致事务回滚的异常类数组 |
rollbackForClassName | 类名数组,必须继承自Throwable | 导致事务回滚的异常类名字数组 |
实现机制
在应用系统调用声明 @Transactional
的目标方法时,Spring Framwork默认使用AOP代理,在代码运行时生成一个代理对象,根据 @Transactional
的属性配置信息,这个代理对象决定该声明的目标方法是否由拦截器 TransactionInterceptor
来进行拦截处理。 在 TransactionInterceptor
拦截时,会在地目标方法开始之前创建并加入事务,并执行目标方法的逻辑,最后根据执行情况是否出现异常,利用抽象事务管理器 AbstractPlatformTransactionManager
操作数据源DataSource提交或回滚事务。