Skip to content
Spring Boot 与事务实践 · 第 2 篇 / 共 2 篇
领域编程与框架
专题Spring 专题
当前序列Spring Boot 与事务实践
阅读位置第 2 篇 / 共 2 篇当前专题第 2 个序列 / 共 6 个序列

Spring 事务传播行为怎么理解:为什么有些回滚生效,有些却没有

Spring 事务最容易让人困惑的地方不是不会写 @Transactional,而是:

  • 明明加了事务
  • 结果回滚没生效
  • 或者嵌套调用后行为和预期不一样

先说结论

Spring 事务真正关键的不是注解本身,而是:

  1. 事务边界落在哪里
  2. 方法调用有没有走代理
  3. 异常有没有真正抛出来
  4. 传播行为是不是符合你的业务意图

一、事务传播在解决什么问题

可以把它理解成:

  • 一个事务方法调用另一个事务方法时,到底要不要共用同一个事务

这件事在订单、库存、优惠券、日志等场景里非常常见。

二、为什么很多人对传播行为没感觉

因为日常最常用的还是默认行为。

只有在这些场景里,传播行为才会变得特别重要:

  • 主业务失败是否要带着子流程一起回滚
  • 审计日志是否要独立提交
  • 某一步失败是否允许外层继续

三、最常见的几个坑

1. 方法内部自调用导致事务失效

这是 Spring 事务最经典的坑之一。

因为事务通常依赖代理生效,如果类内部自己调自己,很多时候就不会走代理。

2. 捕获异常后不再抛出

如果异常被吃掉了,事务通常也就不知道该回滚了。

3. 以为所有异常都会自动回滚

实际使用时一定要明确:

  • 你的异常类型
  • 你的回滚规则

4. 把一个很长的业务流程包进一个大事务

这样很容易带来:

  • 锁持有时间过长
  • 冲突放大
  • 死锁概率上升

四、一个更实用的理解方式

不要先背传播行为定义,而是先问:

  • 这几个步骤是不是一条业务原子链路
  • 失败后我到底想一起回滚,还是局部保留

如果答案不同,传播行为的选择就会清楚很多。

五、什么时候要特别小心

  • 事务里调远程接口
  • 事务里做耗时操作
  • 一个主流程里混入日志、通知、消息发送

这些场景都很容易让事务边界和预期不一致。

一句话总结

Spring 事务传播行为真正要解决的,不是“注解怎么配”,而是:

  • 哪些步骤要绑在一起
  • 哪些步骤应该拆开

把事务边界想明白,很多“为什么没回滚”的问题都会更容易解释。

延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 回看前文会更完整Spring Boot 开发笔记适合把 Spring Boot 开发习惯和事务边界问题放在一起看。Spring 专题 · Spring Boot 与事务实践同专题其他序列 · 共享标签:MySQLSpring 事务隔离级别和丢失更新问题适合把事务隔离、缓存和异步边界放在一起看。Spring 专题 · Spring 事务与治理实践同专题其他序列 · Spring Boot 启动、装配与配置@Conditional 系列注解怎么配合使用适合把自动装配、条件装配、Profile 和循环依赖放回 Spring Boot 启动过程里理解。Spring 专题 · Spring Boot 启动、装配与配置同专题其他序列 · Spring Web 链路与治理能力@Transactional 和 @Async 一起用为什么容易踩坑适合把分发链路、鉴权机制、异步事务和接口治理放在同一条 Web 主线上整理。Spring 专题 · Spring Web 链路与治理能力跨专题关联 · 同场景:基础学习聚合根和事务边界怎么划分适合把 DDD、Saga、TCC 和 BFF、网关边界放在一起看。架构与设计专题 · 分布式系统取舍与边界跨专题关联 · 同场景:基础学习冷热分层和索引生命周期怎么设计适合把 refresh、merge、冷热分层和批量写入放到一起看。Elasticsearch 专题 · Elasticsearch 写入与分层架构
继续阅读Spring Boot 与事务实践当前序列第 2 篇 / 共 2 篇当前专题第 2 个序列 / 共 6 个序列
往前看
上一篇Spring Boot 开发笔记回到当前序列上一章上一序列Spring Web 请求链路从第 1 篇开始:过滤器和拦截器的区别
往后看
下一序列Spring 容器核心机制从第 1 篇开始:BeanFactory 和 ApplicationContext 到底是什么关系

把零散经验整理成可查、可复用、可持续更新的企业级知识门户