为了账号安全,请及时绑定邮箱和手机立即绑定

事务嵌套场景必问:Spring 传播机制如何真正发挥作用?

标签:
Java JavaScript

原文来自于:https://zha-ge.cn/java/102

事务嵌套场景必问:Spring 传播机制如何真正发挥作用?

说起来,有谁没被Spring的事务传播坑过?春风吹又生的坑——面试一问到“REQUIRES_NEW和NESTED到底哪个‘真新建’,谁能真正做到子事务独立提交回滚”,九成人都变成了表情包: “啊?不是加@Transactional就行了么?”

其实,要不是我去年踩了个“史诗级大雷”,我其实也不太敢唧唧歪歪聊这个。下面听我给各位讲个“事务穿越记”。


有一次,产品经理喜提个业务:主流程成功就插日志,日志不插也不能影响主流程。我的第一个反应——这还不简单?日志方法加个@Transactional(propagation = Propagation.REQUIRES_NEW),高高兴兴写代码:

@Service
public class LogService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logAction(String msg) {
        // 记录日志
        // ...
        // 人为制造异常,验证是否独立
        if (msg.contains("fail")) throw new RuntimeException("日志写入失败");
    }
}

主业务大哥自然地调用 logService.logAction(),想着即使记录日志异常抛了,主流程无所谓。


结果上线一测,这主流程特么居然全回滚了!?脸都绿了。我的先入为主的小算盘——“REQUIRES_NEW自动生成新事务,和外面事务无关”,一下给打脸。


踩坑瞬间

真相其实离谱得很,Spring事务传播=面试题,实践全靠玄学踩坑:

  • 内部方法直接调用,事务传播不起效。你以为开了新事务,其实屁都没发生!
  • 没仔细配置事务管理器,REQUIRES_NEW/NESTED压根没新世界可开。
  • 忘了try-catch,异常没吃下来,外层事务直接遭殃。

我的bug现场:

@Service
public class MainService {
    @Transactional
    public void mainJob(String in) {
        // ...
        logService.logAction("fail log"); // 日志抛异常
        // ...
    }
}

控制台异常一大片,数据库里啥都没,主业务说“锅你背”。
为什么?

  • 自己类里直接调用方法,其实Spring的代理根本没接管到你那层!
  • @Transactional其实只对通过Spring代理调用的新事务管用,self调用和普通调用→全白忙活。

经验启示

这场“看似很会,实际踩坑”的事务体验,直接送我几条血的教训:

  • 切记自调用不走Spring代理,传播属性全靠缘分。不信→看官方文档。
  • REQUIRES_NEW真的要跨service注入调用才有用,自己调自己=白忙活。
    • 对,比如@Autowired的service,不是this.XX方法。
  • 外部异常记得try-catch,不然后续流程一锅端!
  • NESTED要求底层是支持savepoint的数据库和DataSource,不是所有场景肤浅理解。
  • 面试时如果他追问,就拿“实际开发要看AOP代理切入点、自调用无效、异常catch防止事务传染”这些说出来,气场升天。

再多说一句:“事务传播机制只有你真正把它们玩出事一两次后,才能发自内心懂。”

最后总结下

事务这玩意,看着就几个注解属性,真到生产环境里就是个大型翻车现场。

传播机制的几个关键点,面试和实战都能用得上:
REQUIRED:默认选手,外有就加入,没就开新。
REQUIRES_NEW:真·新开事务,但必须通过 Spring 代理调用,异常别忘了 catch。
NESTED:玩 savepoint 的,支持局部回滚,前提是底层数据库和事务管理器撑得住。
SUPPORTS / MANDATORY / NEVER:这仨平时少用,但面试官爱问,知道就好。

一句话总结:传播属性本质上是给“事务边界”立规矩,但要生效得满足两个条件:
1.调用路径必须走 Spring 代理(自调用白搭)。
2.事务管理器和数据库要真支持(不然就是纸上谈兵)。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消