Spring 事务的核心概念

Spring 事务管理基于 PlatformTransactionManager 接口实现,提供了统一的事务抽象层,支持编程式事务和声明式事务两种方式。声明式事务通过 @Transactional 注解实现,简化了事务配置。

编程式事务需要手动管理事务的开启、提交和回滚,通常通过 TransactionTemplate 实现。声明式事务通过 AOP 在方法执行前后动态织入事务逻辑,推荐在大多数场景中使用。

事务传播机制详解

事务传播机制定义了多个事务方法相互调用时事务的行为,Spring 支持以下 7 种传播行为:

  • REQUIRED:默认行为,当前存在事务则加入,不存在则新建事务。
  • SUPPORTS:当前存在事务则加入,不存在则以非事务方式运行。
  • MANDATORY:强制要求当前存在事务,不存在则抛出异常。
  • REQUIRES_NEW:无论当前是否存在事务,都新建事务,原有事务暂停。
  • NOT_SUPPORTED:以非事务方式运行,当前存在事务则暂停。
  • NEVER:以非事务方式运行,当前存在事务则抛出异常。
  • NESTED:当前存在事务则在嵌套事务内执行,否则行为同 REQUIRED。

嵌套事务与 REQUIRES_NEW 的区别

NESTED 是真正的嵌套事务,子事务的回滚不会导致父事务回滚,而父事务回滚会导致子事务回滚。嵌套事务依赖保存点机制实现。

REQUIRES_NEW 会完全独立于当前事务,两者之间没有关联,各自独立提交或回滚。新事务会完全挂起原有事务,直到新事务完成。

事务隔离级别

Spring 支持标准的事务隔离级别:

  • DEFAULT:使用底层数据库默认隔离级别。
  • READ_UNCOMMITTED:读未提交,最低隔离级别,可能导致脏读。
  • READ_COMMITTED:读已提交,防止脏读。
  • REPEATABLE_READ:可重复读,防止脏读和不可重复读。
  • SERIALIZABLE:串行化,最高隔离级别,防止所有并发问题。

事务失效的常见场景

  • 方法非 public 修饰,导致 AOP 无法代理。
  • 同类方法自调用,绕过代理对象。
  • 异常类型未在 rollbackFor 配置中声明。
  • 数据库引擎不支持事务,如 MyISAM。
  • 传播行为配置为 NOT_SUPPORTEDNEVER
  • 尝试在非事务上下文中启动嵌套事务。

最佳实践建议

声明式事务尽量保持方法简短,避免长时间事务占用数据库连接。合理选择传播行为和隔离级别,避免过度使用串行化隔离级别导致性能问题。

对于关键业务操作,明确指定 rollbackFor 以确保异常时正确回滚。测试环境验证事务行为是否符合预期,特别是涉及跨服务调用时的事务一致性。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐