Spring 事务管理细节

在 Spring 框架中,@Transactional注解用于声明事务管理

一、事务管理器的原理

1、事务管理器(transactionManager)

  • 作用:控制事务的获取、提交、回滚。
  • 底层默认:JdbcTransactionManager

2、原理

  1. 事务管理器(TransactionManager):控制事务的提交和回滚。
  2. 事务拦截器(TransactionInterceptor):控制事务何时提交和回滚。
    • 回滚触发:completeTransactionAfterThrowing(txInfo, ex)(方法执行出现异常时,执行回滚)。
    • 提交触发:commitTransactionAfterReturning(txInfo)(方法正常返回时,执行提交)。

二、timeout

  1. timeout(同 timeoutString):超时时间,事务超时,秒为单位;

一旦超过约定时间,事务就会回滚。
超时时间是指:从方法开始,到最后一次据库操作结束的时间。
写法可以是:

  1. @Transactional(timeout = 3)
  2. @Transactional(timeoutString = “3”)
    效果相同

三、readOnly:只读优化(优化项,并不能控制什么)

如果对数据库的操作都是只读的,开启可以优化操作速度。

写法:

  1. @Transactional(readOnly = true/false)

四、rollbackFor(同rollbackForClassName)

1.rollbackFor 作用

指明哪些异常需要触发事务回滚(并非所有异常都必然导致回滚)。

2.、异常分类

异常类型 说明
运行时异常 unchecked exception(非受检异常)
编译时异常 checked exception(受检异常)

3.回滚默认机制

异常类型 回滚规则
运行时异常 回滚
编译时异常 不回滚

4.写法:

1
2
3
@Transactional(rollbackFor = {IOException.class}, //IO异常
rollbackForClassName = "java.lang.Exception") //所有异常

//指定IO异常可以回滚
【可以指定哪些异常需要回滚】:
【回滚 = 运行时异常 + 指定回滚异常】

五、noRollbackFor(同noRollbackForClassName)

1.noRollbackFor作用

指明哪些异常不需要回滚。
【不回滚 = 编译时异常 + 指定回滚异常】

2.写法

1
@Transactional(norollbackFor = {ArithmeticException.class}, //数学运算异常

数学运算异常属于运行时异常,会回滚,用noRollbackFor之后,会不进行回滚。

六、 isolation:隔离级别

Spring 定义了 5 种隔离级别,对应数据库的 SQL 标准:

  1. DEFAULT(默认)

    • 含义:使用数据库默认的隔离级别(大多数数据库默认是READ_COMMITTED,如 MySQL、SQL Server)。
    • 使用场景:大多数情况下的默认选择,无需显式指定。
  2. READ_UNCOMMITTED(读未提交)

    • 含义:一个事务可以读取另一个未提交事务的数据。
    • 问题:可能出现脏读(读取到未提交的无效数据)。
    • 性能:最高(并发能力强),但一致性最低。
  3. READ_COMMITTED(读已提交)

    • 含义:一个事务只能读取另一个已提交事务的数据。
    • 解决:避免脏读,但可能出现不可重复读(同一事务中多次读取同一数据,结果不一致)。
    • 适用:大多数互联网应用,平衡了一致性和性能。
  4. REPEATABLE_READ(可重复读)

    • 含义:同一事务中多次读取同一数据,结果始终一致(不受其他事务提交影响)。
    • 解决:避免脏读不可重复读,但可能出现幻读(读取范围内的数据总量变化)。
    • 备注:MySQL 的默认隔离级别(通过 MVCC 机制实现)。
  5. SERIALIZABLE(串行化)

    • 含义:事务完全串行执行(最严格的隔离),相当于单线程处理。
    • 解决:避免所有并发问题(脏读、不可重复读、幻读)。
    • 问题:性能极低,并发能力差。
    • 适用:数据一致性要求极高的场景(如金融核心交易)。

七、[[propagation:传播行为]]