跳到正文
返回Spring 与 MySQL

Spring 与 MySQL 整理

Spring 事务不生效,先检查调用有没有经过代理

自调用、异常类型、异步线程和事务管理器,都可能影响结果。

先回答:同一个类里,一个方法调用另一个带 @Transactional 的方法,会开启新事务吗?

在常见的 Spring 代理事务模式下,同一对象内部的自调用通常不会经过事务代理,因此被调用方法上的事务配置不会按一次新的代理拦截生效。但如果外层已经有事务,内部代码仍可能在外层事务中执行,不能把“注解未被拦截”直接说成“完全没有事务”。

先判断调用路径

外部对象通过 Spring 管理的代理调用方法,事务拦截器才有机会介入。自己 new 出来的对象、绕开代理的调用、常见代理模式下的自调用,都应优先排查。

可以把需要独立事务边界的操作移到另一个 Spring Bean,通过正常注入调用;也可以按场景使用 TransactionTemplate。不要为了让注解生效而盲目增加代理层。

异常是否真的触发回滚

默认情况下,声明式事务通常对 RuntimeException 和 Error 回滚;受检异常默认不会按同样规则回滚,可以按需指定 rollbackFor。

如果把异常捕获后直接返回成功,事务框架未必还能按预期判断失败。是否已经被标记为 rollback-only、是否最终出现 UnexpectedRollbackException,应结合整个传播链分析。

线程与数据库也要一起看

  • 常见的命令式事务上下文绑定在线程上,不能假设新建线程或异步方法自然继承原调用线程的事务。
  • 确认使用了正确的数据源、事务管理器,以及数据库和表是否支持所需事务行为。
  • 方法可见性与代理限制要结合 Spring 版本、代理类型、配置判断,不要背成跨版本通用结论。
  • 事务保证原子性不代表业务天然幂等;结算、扣款等仍需要业务唯一约束、状态检查与锁策略。

延伸阅读

以上为个人整理。涉及版本实现和线上使用时,请结合对应文档与实际测试判断。