38. JTA 的分布式事务
Spring Boot 通过使用Atomikos或Bitronix嵌入式事务 Management 器,支持跨多个 XA 资源的分布式 JTA 事务。部署到合适的 Java EE 应用程序服务器时,还支持 JTA 事务。
当检测到 JTA 环境时,使用 Spring 的JtaTransactionManager
来 Management 事务。自动配置的 JMS,DataSource 和 JPA Bean 已升级为支持 XA 事务。您可以使用标准的 Spring 习惯用法(例如@Transactional
)来参与分布式事务。如果您在 JTA 环境中,并且仍要使用本地事务,则可以将spring.jta.enabled
属性设置为false
以禁用 JTA 自动配置。
38.1 使用 Atomikos Transaction manager
Atomikos是流行的开源事务 Management 器,可以嵌入到您的 Spring Boot 应用程序中。您可以使用spring-boot-starter-jta-atomikos
Starter 引入适当的 Atomikos 库。 Spring Boot 自动配置 Atomikos 并确保将适当的depends-on
设置应用于您的 Spring Bean,以正确启动和关闭 Sequences。
默认情况下,Atomikos 事务日志将写入应用程序主目录(应用程序 jar 文件所在的目录)中的transaction-logs
目录。您可以通过在application.properties
文件中设置spring.jta.log-dir
属性来自定义此目录的位置。以spring.jta.atomikos.properties
开头的属性也可以用于自定义 Atomikos UserTransactionServiceImp
。有关完整的详细信息,请参见AtomikosProperties Javadoc。
Note
为了确保多个事务 Management 器可以安全地协调同一资源 Management 器,必须为每个 Atomikos 实例配置一个唯一的 ID。默认情况下,此 ID 是运行 Atomikos 的计算机的 IP 地址。为了确保 Producing 的唯一性,应为应用程序的每个实例将spring.jta.transaction-manager-id
属性配置为不同的值。
38.2 使用 Bitronix Transaction manager
Bitronix是流行的开源 JTA 事务 Management 器实现。您可以使用spring-boot-starter-jta-bitronix
Starter 程序将适当的 Bitronix 依赖项添加到您的项目中。与 Atomikos 一样,Spring Boot 自动配置 Bitronix 并对您的 bean 进行后处理,以确保启动和关闭 Sequences 正确。
默认情况下,Bitronix 事务日志文件(part1.btm
和part2.btm
)被写入应用程序主目录中的transaction-logs
目录。您可以通过设置spring.jta.log-dir
属性来自定义此目录的位置。以spring.jta.bitronix.properties
开头的属性也绑定到bitronix.tm.Configuration
bean,从而可以进行完全自定义。有关详情,请参见Bitronix documentation。
Note
为了确保多个事务 Management 器可以安全地协调同一资源 Management 器,必须为每个 Bitronix 实例配置唯一的 ID。默认情况下,此 ID 是运行 Bitronix 的计算机的 IP 地址。为了确保 Producing 的唯一性,应为应用程序的每个实例将spring.jta.transaction-manager-id
属性配置为不同的值。
38.3 使用 Java EE 托管事务 Management 器
如果将 Spring Boot 应用程序打包为war
或ear
文件并将其部署到 Java EE 应用程序服务器,则可以使用应用程序服务器的内置事务 Management 器。 Spring Boot 尝试通过查看常见的 JNDI 位置(java:comp/UserTransaction
,java:comp/TransactionManager
等)来自动配置事务 Management 器。如果使用应用程序服务器提供的事务服务,通常还需要确保所有资源都由服务器 Management 并通过 JNDI 公开。 Spring Boot 通过在 JNDI 路径(java:/JmsXA
或java:/XAConnectionFactory
)中查找ConnectionFactory
来尝试自动配置 JMS,您可以使用spring.datasource.jndi-name property来配置DataSource
。
38.4 混合 XA 和非 XA JMS 连接
使用 JTA 时,主要的 JMS ConnectionFactory
bean 支持 XA,并参与分布式事务。在某些情况下,您可能希望通过使用非 XA ConnectionFactory
处理某些 JMS 消息。例如,您的 JMS 处理逻辑可能需要比 XA 超时更长的时间。
如果要使用非 XA ConnectionFactory
,则可以注入nonXaJmsConnectionFactory
bean 而不是@Primary
jmsConnectionFactory
bean。为了保持一致性,还使用 Bean 别名xaJmsConnectionFactory
提供了jmsConnectionFactory
bean。
以下示例显示了如何注入ConnectionFactory
个实例:
// Inject the primary (XA aware) ConnectionFactory
@Autowired
private ConnectionFactory defaultConnectionFactory;
// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)
@Autowired
@Qualifier("xaJmsConnectionFactory")
private ConnectionFactory xaConnectionFactory;
// Inject the non-XA aware ConnectionFactory
@Autowired
@Qualifier("nonXaJmsConnectionFactory")
private ConnectionFactory nonXaConnectionFactory;
38.5 支持备用嵌入式事务 Management 器
XAConnectionFactoryWrapper和XADataSourceWrapper接口可用于支持其他嵌入式事务 Management 器。这些接口负责包装XAConnectionFactory
和XADataSource
bean 并将它们作为常规ConnectionFactory
和DataSource
bean 公开,它们透明地注册了分布式事务。数据源和 JMS 自动配置使用 JTA 变体,前提是您拥有JtaTransactionManager
bean 和在ApplicationContext
中注册了适当的 XA 包装 bean。
BitronixXAConnectionFactoryWrapper和BitronixXADataSourceWrapper提供了有关如何编写 XA 包装程序的良好示例。