开篇:为什么银行转账不能只转一半?
想象你站在 ATM 机前,准备把 100 元从 A 卡转到 B 卡。操作过程实际上是 6 个步骤:
- 从 A 账户读取余额(500)
- A 账户减去 100(500 - 100 = 400)
- 把 400 写回 A 账户
- 从 B 账户读取余额(500)
- B 账户加上 100(500 + 100 = 600)
- 把 600 写回 B 账户
如果执行到第 3 步之后突然断电,A 卡扣了 100,B 卡一分没多,钱凭空蒸发了。
大约 21 分钟
想象你站在 ATM 机前,准备把 100 元从 A 卡转到 B 卡。操作过程实际上是 6 个步骤:
如果执行到第 3 步之后突然断电,A 卡扣了 100,B 卡一分没多,钱凭空蒸发了。
你一定遇到过这种场景:明明方法上加了 @Transactional,数据库操作却没有回滚。你反复检查代码,确认异常确实抛出了,可事务就是不起作用。
这大概是 Spring 开发中最经典的"灵异事件"了。而且它往往发生在最不该出问题的时候——线上已经跑了一段时间,某位同事改了一行代码,事务就悄悄失效了。
要理解它为什么不生效,就得先搞清楚 Spring 事务到底是怎么工作的。这篇文章会带你从原理出发,一步步揭开声明式事务的面纱。