分布式事务为什么难
Spring 事务用起来简单,但失效场景非常多。很多人遇到过 @Transactional 不生效的情况,却不知道原因。本文把日常开发中常见的坑和对应的排查思路整理出来,帮你避免踩坑。
先从业务问题出发
架构设计不要先问“用什么中间件”,而要先问业务目标:是要提升吞吐、解耦系统、保证最终一致,还是降低峰值压力?不同目标对应的方案完全不同。
一个典型流程
以订单创建后发送通知为例:
- 订单服务先保存订单。
- 写入消息或事件。
- 通知服务异步消费。
- 消费端做好幂等,避免重复通知。
伪代码可以这样理解:
orderService.create(order); |
消费端必须能处理重复消息:
if (processed(messageId)) { |
设计时要补的问题
- 消息发送失败怎么办?
- 消费失败是否重试?
- 重复消费如何保证幂等?
- 下游长时间不可用时如何降级?
核心要点
事务失效的常见原因:非 public 方法、自调用、异常被吞掉、错误的传播级别
事务传播级别决定了方法之间的事务关系,REQUIRED 是默认值
使用 @Transactional(rollbackFor = Exception.class) 确保异常回滚
编程式事务在某些场景下比声明式事务更灵活
总结
事务管理是保证数据一致性的关键。理解事务的工作机制和常见陷阱,能帮你写出更健壮的代码。在实际项目中,合理配置事务边界非常重要。