spring源码学习(四)spring复习之事务

读的问题

脏读

事务A开启事务,事务B开启事务,事务B增加或修改数据,但是未提交,事务A到读取了未提交的数据
image

不可重复读

image

演示

事务A先查,得到1000
image
事务B修改,并提交
image
事务A再查,得到800
image

解决方案

image

  • 相当于事务A,select where id=1时,给这行数据加了锁,其他事务无法修改

幻读

image

  • 幻读强调的是insert

演示

事务A统计表总数为1000,事务B新增了100条,并提交事务,事务A又统计,表总数为1100。

解决

image

隔离级别

image

数据库的隔离级别

image

默认隔离级别

image

image

传播属性

image

举例理解

示例一

Service1的save
image

Service2的save
image

  • 假设Controller层调用Service1的save1的方法,然后调用Service2的save2方法
  • Controller层没有@Transactional,所以Service1的save1被调用时,要创建事务,而save2被调用时,要融入进save1的事务

示例二

image
image
image

捕获异常之REQUIRED

image
image

  • 两个方法都会回滚

捕获异常之REQUIRES_NEW

情况一

image
image

  • save2会回滚,save1不会回滚
  • save2是事务2,save1是事务1,save2内部出现了异常,回滚,而save1捕获了异常,不会回滚

情况二

image

  • save2会回滚,save1会回滚
  • save2出异常了,往外抛,save1又没捕获,那save1相当于接住了异常,出现了异常

事务超时

image

使用场景

image

事务失效的原因

1. 非 public 方法‌

现象‌:private/protected 方法添加 @Transactional 无效
原因‌:Spring AOP 代理仅拦截 public 方法

2. 同类内部自调用‌

‌现象‌:methodA() 调用同类中的 @Transactional methodB() 事务失效
‌原因‌:自调用绕过代理对象
‌解决‌:
方案1:拆分到不同类

@Service
public class ServiceB {
    @Transactional
    public void methodB() { ... }
}

方案2:通过代理对象调用(需开启 exposeProxy)

((ServiceA) AopContext.currentProxy()).methodB();
现象‌:static/final 方法事务不生效

原因‌:无法生成代理子类
解决‌:避免在 final/static 方法上使用 @Transactional。

捕获异常未抛出‌

‌现象‌:try-catch 吞没异常导致不回滚
解决:

@Transactional
public void process() {
    try {
        dbOperation();
    } catch (Exception e) {
        //重新抛出或标记回滚
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        throw new RuntimeException(e);
    }
}
错误异常类型‌

现象‌:抛出 IOException 等检查异常不回滚
原因‌:默认仅回滚 RuntimeException 和 Error
解决:

@Transactional(rollbackFor = Exception.class) // 指定回滚异常
‌数据库引擎不支持‌

‌现象‌:MySQL 使用 MyISAM 引擎(不支持事务)
‌解决‌:更换为 InnoDB 引擎:

未启用事务管理‌

‌现象‌:缺少 @EnableTransactionManagement
‌解决‌:在配置类添加注解启用事务。

多数据源未指定管理器‌

‌现象‌:多数据源场景事务混乱
‌解决‌:

@Transactional("orderTransactionManager") //指定事务管理器
public void createOrder() { ... }
posted @ 2026-03-12 15:33  dvdhellohaha  阅读(21)  评论(0)    收藏  举报