跳到主要内容

声明式事务管理

DeepSeek V3 中英对照 Declarative Transaction Management

备注

大多数 Spring 框架用户选择声明式事务管理。这种选择对应用程序代码的影响最小,因此最符合非侵入式轻量级容器的理念。

Spring 框架的声明式事务管理是通过 Spring 面向切面编程(AOP)实现的。然而,由于事务切面代码随 Spring 框架发行版提供,并且可以以样板方式使用,因此通常不需要理解 AOP 概念即可有效使用此代码。

Spring 框架的声明式事务管理与 EJB CMT 类似,因为你可以将事务行为(或不包含事务行为)指定到单个方法级别。如果需要,你可以在事务上下文中调用 setRollbackOnly()。这两种事务管理类型之间的区别是:

  • 与 EJB CMT 不同,后者与 JTA 绑定,Spring 框架的声明式事务管理适用于任何环境。它可以通过调整配置文件与 JTA 事务或本地事务(使用 JDBC、JPA 或 Hibernate)一起工作。

  • 你可以将 Spring 框架的声明式事务管理应用于任何类,而不仅仅是像 EJB 这样的特殊类。

  • Spring 框架提供了声明式的回滚规则,这是一个 EJB 没有等效功能。Spring 提供了对回滚规则的编程式和声明式支持。

  • Spring 框架允许你通过使用 AOP 自定义事务行为。例如,你可以在事务回滚的情况下插入自定义行为。你还可以在事务通知之外添加任意的通知。而在 EJB CMT 中,除了使用 setRollbackOnly() 之外,你无法影响容器的事务管理。

  • Spring 框架不支持像高端应用服务器那样跨远程调用传播事务上下文。如果你需要这一功能,我们建议你使用 EJB。然而,在使用此类功能之前请仔细考虑,因为通常情况下,人们不希望事务跨越远程调用。

回滚规则的概念非常重要。它们允许你指定哪些异常(和可抛出对象)应该导致自动回滚。你可以在配置中以声明方式指定这一点,而不是在 Java 代码中。因此,尽管你仍然可以在 TransactionStatus 对象上调用 setRollbackOnly() 来回滚当前事务,但大多数情况下,你可以指定一个规则,即 MyApplicationException 必须始终导致回滚。这种选项的显著优势是业务对象不依赖于事务基础架构。例如,它们通常不需要导入 Spring 事务 API 或其他 Spring API。

尽管 EJB 容器的默认行为会在系统异常(通常是运行时异常)时自动回滚事务,但 EJB CMT 在应用程序异常(即除了 java.rmi.RemoteException 之外的已检查异常)时不会自动回滚事务。虽然 Spring 的声明式事务管理默认行为遵循 EJB 约定(仅对未检查的异常自动回滚),但自定义此行为通常很有用。

章节摘要

📄️ 使用 AspectJ 的 @Transactional

你也可以通过使用 AspectJ 切面在 Spring 容器之外使用 Spring 框架的 @Transactional 支持。为此,首先用 @Transactional 注解标注你的类(以及可选的类方法),然后将你的应用程序与定义在 spring-aspects.jar 文件中的 org.springframework.transaction.aspectj.AnnotationTransactionAspect 进行链接(织入)。你还必须为切面配置一个事务管理器。你可以使用 Spring 框架的 IoC 容器来处理切面的依赖注入。配置事务管理切面的最简单方法是使用 \<tx:annotation-driven/> 元素,并将 mode 属性指定为 aspectj,如使用 @Transactional 中所述。因为我们在这里关注的是在 Spring 容器之外运行的应用程序,所以我们向你展示如何以编程方式实现这一点。