理解 Spring 框架的声明式事务实现
仅仅告诉你使用 @Transactional
注解来标注你的类,并在配置中添加 @EnableTransactionManagement
,然后期望你理解这一切是如何工作的,这是不够的。为了提供更深入的理解,本节将在与事务相关的问题背景下,解释 Spring 框架声明式事务基础设施的内部工作原理。
关于 Spring 框架的声明式事务支持,最重要的概念是这种支持是通过 AOP 代理 启用的,并且事务通知是由元数据(目前基于 XML 或注解)驱动的。AOP 与事务元数据的结合产生了一个 AOP 代理,该代理使用 TransactionInterceptor
结合适当的 TransactionManager
实现来驱动方法调用周围的事务。
Spring AOP 的内容在 AOP 部分 中有所介绍。
Spring Framework 的 TransactionInterceptor
为命令式和响应式编程模型提供了事务管理。拦截器通过检查方法返回类型来检测所需的事务管理风格。返回响应式类型(如 Publisher
或 Kotlin Flow
,或其子类型)的方法适用于响应式事务管理。所有其他返回类型(包括 void
)则使用命令式事务管理的代码路径。
事务管理风格影响所需的交易管理器。命令式事务需要一个 PlatformTransactionManager
,而响应式事务则使用 ReactiveTransactionManager
实现。
@Transactional
通常与由 PlatformTransactionManager
管理的线程绑定事务一起使用,将事务暴露给当前执行线程中的所有数据访问操作。注意:这不会传播到方法内新启动的线程中。
由 ReactiveTransactionManager
管理的响应式事务使用 Reactor 上下文而不是线程本地属性。因此,所有参与的数据访问操作都需要在同一个响应式管道的相同 Reactor 上下文中执行。
当配置为 ReactiveTransactionManager
时,所有事务划分的方法都应返回一个响应式管道。Void 方法或常规返回类型需要与常规的 PlatformTransactionManager
关联,例如通过相应 @Transactional
声明的 transactionManager
属性。
下图展示了在事务代理上调用方法的概念视图: