标准答案

  1. 确认对象由 Spring 容器创建,调用经过代理,方法可被代理机制拦截。
  2. 确认异常是否从事务边界抛出,以及 checked exception 是否配置了回滚规则。
  3. 确认数据库连接、数据源和事务管理器一致,SQL 确实在同一事务连接中执行。
  4. 通过日志、事务同步回调、数据库观察和最小复现验证,而不是只看注解是否存在。

题目解析

先确认调用对象是否由容器创建且经过代理,再确认异常是否从事务边界抛出,最后确认 SQL 使用了正确数据源和同一事务连接。注解存在不代表运行时边界成立。

异常被 catch 后不再抛出、checked exception 不在回滚规则中、事务已经提交或内部自调用,都会让“看起来应该回滚”的代码产生不同结果。

多数据源场景要明确事务管理器和数据源绑定,必要时用最小复现插入可观察记录,结合事务日志和数据库结果验证,而不是只看日志里打印了事务注解。

常见误区

  • 误区:catch 后不重新抛出却期待回滚。改正:配置回滚规则或重新抛出能触发回滚的异常,并验证业务状态。
  • 误区:用方法内部自调用测试事务。改正:通过代理 Bean 的外部调用进入事务,或调整服务边界。
  • 误区:多个数据源却使用错误事务管理器。改正:显式绑定数据源、事务管理器和 mapper,使用提交后数据验证。

作者信息