@Transactional的Propagation.REQUIRES_NEW和(propagation = Propagation.NESTED测试

一、外部方法调内部方法,外部有@Transactional,内部有@Transactional(propagation = Propagation.REQUIRES_NEW)

// 外部事务
@Transactional
public void outerMethod() {
    
    innerMethod(); 
}

// 内部事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void innerMethod() {
    
}
  • 场景1:内部事务抛出异常,外层不捕获

    • 结果:内外事务均回滚。
  • 场景2:内部事务抛出异常,外层捕获异常

    • 结果:内部事务回滚,外层事务提交。
  • 场景3:内部事务正常提交,外层事务后续抛出异常

    • 结果:内部事务提交有效,外层事务回滚。

结论
1.REQUIRES_NEW会新开启事务,外部事务异常不会影响内部事务的提交/回滚
2.REQUIRES_NEW的内部事务的异常,可能会影响外部事务的回滚

  • 内部事务因异常回滚后,异常会传播到外层方法,导致外层事务也回滚
  • 若外层方法通过try-catch捕获了内部方法抛出的异常,外层事务不会因内部事务的异常而回滚。此时,只有内部事务自身回滚。

二、外部方法调内部方法,外部有@Transactional,内部有@Transactional(propagation = Propagation.NESTED)

结论:
1.Propagation.NESTED会新开启事务,外部事务异常不会影响内部事务的提交/回滚

  • 内部事务的提交需要等待外部事务最终提交,外部事务回滚会导致内部事务回滚。
  • 内部事务可以独立回滚(回滚到保存点),但外部事务仍可继续执行。

2.Propagation.NESTED的内部事务的异常,可能会影响外部事务的回滚

  • 如果内部事务的异常未被捕获:NESTED 事务回滚到保存点,同时异常会传播到外部事务,默认导致外部事务回滚
  • 如果内部事务的异常被捕获:仅内部事务回滚到保存点,外部事务可继续执行。

机制:

传播行为内部事务回滚外部事务回滚
REQUIRES_NEW仅回滚内部事务,不影响外部事务。仅回滚外部事务,不影响内部事务。
NESTED回滚到保存点,不影响外部事务其他操作。回滚整个事务(包括所有保存点后的操作)。

实际应用场景:
(1) REQUIRES_NEW 适用场景

需要完全独立的事务:

  • 记录操作日志(即使主事务回滚,日志仍需保留)。

  • 异步任务触发(如发送消息到消息队列)。

(2) NESTED 适用场景

需要部分操作可回滚:

  • 订单创建成功后,扣减库存失败时仅回滚库存操作,保留订单记录。

  • 批量处理数据时,允许单条记录失败回滚,其他记录继续处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值