Spring事务管理

事务


一系列操作组成的工作单元称为事务。事务必须满足 ACID(原子性、一致性、隔离性、持久性)

事务要素 意义
原子性Atomicity 事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做
一致性Consistency 在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数 据依然处于正确的状态,即数据完整性约束没有被破坏,如 A 给 B 转账,不论转账成功与否转账之后 的 A 和 B 的账户总额和转账之前是相同的。
隔离性Isolation 当多个事务处于并发访问同一个数据库资源时,事务之间相互影响程度,不同 的隔离级别决定了各个事务对数据资源访问的不同行为。
持久性Durability 事务一旦执行成功,它对数据库的数据的改变是不可逆的。

数据库并发问题:详见事务并发

事务类型


事务类型 作用
本地事务 就是普通事务,能保证单台数据库上的操作的 ACID,被限定在一台数据库上
分布式事务 涉及多个数据库源的事务,即跨越多台同类或异类数据库的事务(由每台数据库的本地事 务组成的),分布式事务旨在保证这些本地事务的所有操作的 ACID,使事务可以跨越多台数据库; JDBC 事务和 JTA 事务

JDBC 事务:数据库事务类型中的本地事务,通过 Connection 对象的控制来管理事务。

JTA(Java Transaction API)事务:Java EE 数据库事务规范,JTA 只提供了事务管理接口,由应用程序服务器厂商提供实现,JTA事务比 JDBC 更强大,支持分布式事务。

是否通过编程实现事务 分为声明式事务和编程式事务

  • 编程式事务:通过编写代码来管理事务
  • 声明式事务:通过注解或 XML 配置来管理事务。

Spring 事务管理


Spring 的事务管理主要包括 3 个接口:

接口名 作用
PlatformTransactionManager 根据 TransactionDefinition 提供的事务属性配置信息,创建事务。
TransactionDefinition 封装事务的隔离级别和超时时间,是否为只读事务和事务的隔离级别和传播规则等事务属性
TransactionStatus 封装了事务的具体运行状态。是否是新开启的事务,是否已经提交事务,设置当前事务为 rollback-only 等。

PlatformTransactionManager


PlatformTransactionManager接口, 统一处理事务相关操作,

  • getTransaction(TransactionDefinition) : TransactionStatus 创建或者返回事务
  • commit(TransactionStatus) : void 提交事务,如果事务状态被标识为 rollback-only,该方法执行回滚事务操作。
  • rollback(TransactionStatus) : void 回滚事务,commit 方法抛出异常时,rollback 会被隐式调用。

常用的事务管理器:

DataSourceTransactionManager - 支持 JDBC,MyBatis
HibernateTransactionManager - 支持 Hibernate

TransactionDefinition

事务的隔离级别、超时时间、是否为只读事务、转播规则等事务属性。

隔离级别:解决并发事务出现的问题

  • isolation_default 默认隔离级别,使用数据库默认隔离级别
  • isolation_read_uncommitted
  • isolation_read_committed
  • isolation_repeatable_read 可重复读
  • isolation_serializable 序列化

TransactionStatus

事务运行状态,是否是新开启事务,是否已经提交,设置当前事务为 rollback-only 等。

一个事务中调用其他事务方法,Spring 支持7中事务传播行为:

  1. 遵从当前事务
    • required 如果当前存在事务,加入该事务,如果当前没有事务,新建一个事务,默认值
    • supports 如果当前存在事务,就加入该事务,如果当前没有事务,就以非事务的方式运行
    • mandatory 使用当前事务执行,如果没有当前事务,直接抛异常
  2. 不遵从当前事务
    • requires_new 不管当前是否存在事务,每次都创建新的事务
    • not_supported 以非事务方式执行,如果当前存在事务,暂停当前事务,并以非事务方式运行
    • never 不支持事务,如果当前存在事务,抛出异常,IllegalTransactionStateException
  3. 嵌套事务
    • nested 如果当前存在事务,在内部事务内执行,如果当前不存在事务,创建一个新的事务并执行。嵌套事务使用数据库中的保存点 savepoint 实现,嵌套事务回滚不影响外部事务,但外部事务回滚将导致嵌套回滚。DataSourceTransactionManager 默认支持,HibernateTransactionManager 默认不支持,需要手动开启。

事务配置


事务增强,好比是一个环绕增强,Spring专门为这一个特殊的环绕增强提供了命名空间,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- what -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource"></property>
</bean>
<!-- when -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- where -->
<aop:config>
<aop:pointcut expression="execution(* cn.lizhaoloveit.aop.service.*Service.*(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>

在 Mybatis-config.xml 中可以知道,要想设置事务,必须有一个连接池,所以 DataSourceTransactionManager 有一个属性 dataSource,需要有一个连接池对象。

1
2
3
4
5
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>

tx:method 可配置属性如下,

事务开启在业务层,不会开在持久层和控制层

属性 必须 default 描述
name 事务管理的方法,可使用通配符*
propagation × required 事务传播规则,比如:supports、requires_new
isolation × default 事务隔离级别,default:使用数据库默认的事务隔离级别、其他级别是spring 模拟的
read-only × false 只读事务针对查询操作
timeout × -1 事务超时时间(秒),-1表示底层事务系统决定
rollback-for × runtimeException 需要回滚的异常类型,多个使用,隔开
no-rollback-for × Exception 遇到这个类型的异常不回滚

CRUD 通用事务配置

1
2
3
4
5
6
7
8
9
10
11
12
<bean> </bean>
<!-- 配置管理事务的增强 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- service 中查询方法 -->
<tx:method name="get*" read-only="true"/>
<tx:method name="list*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<!-- 其他方法 -->
<tx:method name="*"/>
<tx:attributes>
</tx:advice>

关联 pointcut 和 txAdvice,拦截哪些方法

1
2
3
4
5
<!-- where -->
<aop:config>
<aop:pointcut expression="execution(* cn.lizhaoloveit.aop.service.*Service.*(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
文章作者: Ammar
文章链接: http://lizhaoloveit.cn/2019/08/03/Spring%E4%BA%8B%E5%8A%A1%E7%AE%A1%E7%90%86/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ammar's Blog
打赏
  • 微信
  • 支付宝

评论