Skip to content

事务管理 (Transaction Management)

全面的事务支持是使用 Spring 框架最令人信服的原因之一。Spring 框架为事务管理提供了一致的抽象,带来了以下好处:

  • 跨不同事务 API 的一致编程模型:例如 Java 事务 API (JTA)、JDBC、Hibernate 和 Java 持久化 API (JPA)。
  • 支持声明式事务管理
  • 更简单的编程式事务管理 API:相比 JTA 等复杂的事务 API,其 编程式方式 更加简单易用。
  • 与 Spring 数据访问抽象的卓越集成

以下各节描述了 Spring 框架的事务功能和技术:

本章还包括关于最佳实践、应用服务器集成 以及 常见问题的解决方案 的讨论。


补充教学

1. 为什么“一致性”如此重要?

在没有 Spring 之前,如果你从本地 JDBC 事务切换到分布式跨库事务(JTA),你需要重写大量的底层代码。JDBC 使用 connection.commit(),而 JTA 需要操作 UserTransaction

Spring 的威力:它通过 PlatformTransactionManager(及其现代的响应式变体 ReactiveTransactionManager)将底层实现细节屏蔽。无论底层是单机还是分布式,你的业务代码通常只需要一个简单的 @Transactional 注解。这种“一次编写,到处运行”的特性极大地降低了系统架构演进的成本。

2. 声明式 vs 编程式:核心权衡

  • 声明式事务(主流推荐):通过 AOP 实现,对业务代码几乎零入侵。它非常适合大部分遵循“成功提交,异常回滚”规则的业务场景。
  • 编程式事务(特殊场景):当你需要对事务边界进行极其细腻的控制(例如在长任务中只针对某一段代码开启独立事务),或者你的业务逻辑涉及到非常复杂的手动回滚决策时,编程式事务(如 TransactionTemplate)会更加直接。

3. 注意事务的“幻觉”

虽然 @Transactional 让事务变得异常简单,但如果不了解其背后的代理机制,很容易踩坑。常见的“失效”场景包括:

  • 同类方法自调用:一个没有注解的方法调用同一个类中带 @Transactional 的方法,事务不会生效。
  • 异常被静默处理:如果你在业务逻辑里 try-catch 了异常且没有重新抛出,Spring 将无法得知需要回滚。

4. 预览:我们将深入讨论什么?

在本章后续内容中,我们将深入拆解以下三个事务核心属性:

  1. 传播行为 (Propagation):当一个事务方法调用另一个事务方法时,该怎么办?(如 REQUIRED vs REQUIRES_NEW
  2. 隔离级别 (Isolation):如何平衡外部并发访问与数据一致性?(脏读、不可重复读、幻读)
  3. 回滚规则:哪些异常应该回滚?哪些不应该?

Based on Spring Framework.