同一个服务里写两个数据库,一个 @Transactional 管得住吗?嵌套两个事务模板呢?提交时一方失败会怎样?这篇在 Spring Framework 7.0.9 和 MySQL 26.7.0 上用杀连接制造提交失败,逐个量出来。
(0)@Transactional(txA) 写 A 和 B,成功 → 正常返回 A 库 1 行,B 库 1 行 → 一致 (1)@Transactional(txA) 写 A 和 B,最后抛异常 → IllegalStateException ← IllegalStateException A 库 0 行,B 库 1 行 → 不一致 (2)嵌套模板:A 外 B 内,都成功 → 正常返回 A 库 1 行,B 库 1 行 → 一致 (3)嵌套模板:B 内层提交之后,A 外层抛异常 → IllegalStateException ← IllegalStateException A 库 0 行,B 库 1 行 → 不一致 (4)嵌套模板:A 在提交前连接被杀(B 先提交) → TransactionSystemException ← SQLNonTransientConnectionException A 库 0 行,B 库 1 行 → 不一致 (5)反过来:B 外 A 内,A 的连接在 A 提交前被杀 → TransactionSystemException ← SQLNonTransientConnectionException A 库 0 行,B 库 0 行 → 一致 (6)B 外 A 内,A 先提交,B 的连接在 B 提交前被杀 → TransactionSystemException ← EOFException A 库 1 行,B 库 0 行 → 不一致
一个方法同时写两个库,另一个库的写入不受 @Transactional 控制,不会回滚。