4.17 使用JTA的分布式事务

优质
小牛编辑
163浏览
2023-12-01

Spring Boot通过使用Atomikos或Bitronix嵌入式事务管理器支持跨多个XA资源的分布式JTA事务。 部署到合适的Java EE Application Server时,也支持JTA事务。

检测到JTA环境时,Spring的JtaTransactionManager用于管理事务。 自动配置的JMS,DataSource和JPA bean已升级为支持XA事务。 您可以使用标准的Spring惯用语(例如@Transactional)来参与分布式事务。 如果您在JTA环境中并且仍想使用本地事务,则可以将spring.jta.enabled属性设置为false以禁用JTA自动配置。

4.17.1 使用Atomikos事务管理器

Atomikos是一个流行的开源事务管理器,可以嵌入到Spring Boot应用程序中。 您可以使用spring-boot-starter-jta-atomikos Starter来获取相应的Atomikos库。 Spring Boot自动配置Atomikos并确保将适当的依赖设置应用于Spring bean,以便正确启动和关闭顺序。

默认情况下,Atomikos事务日志将写入应用程序主目录(应用程序jar文件所在的目录)中的transaction-logs目录。 您可以通过在application.properties文件中设置spring.jta.log-dir属性来自定义此目录的位置。 以spring.jta.atomikos.properties开头的属性也可用于自定义Atomikos UserTransactionServiceImp。 有关完整的详细信息,请参阅AtomikosProperties Javadoc。

为确保多个事务管理器可以安全地协调相同的资源管理器,必须使用唯一ID配置每个Atomikos实例。 默认情况下,此ID是运行Atomikos的计算机的IP地址。 要确保生产中的唯一性,您应该为应用程序的每个实例配置spring.jta.transaction-manager-id属性,并使用不同的值.

4.17.2 使用Bitronix事务管理器

Bitronix是一种流行的开源JTA事务管理器实现。 您可以使用spring-boot-starter-jta-bitronix starter为您的项目添加适当的Bitronix依赖项。 与Atomikos一样,Spring Boot会自动配置Bitronix并对bean进行后处理,以确保启动和关闭顺序正确。

默认情况下,Bitronix事务日志文件(part1.btm和part2.btm)将写入应用程序主目录中的transaction-logs目录。 您可以通过设置spring.jta.log-dir属性来自定义此目录的位置。 以spring.jta.bitronix.properties开头的属性也绑定到bitronix.tm.Configuration bean,允许完全自定义。 有关详细信息,请参阅Bitronix文档。

为确保多个事务管理器可以安全地协调相同的资源管理器,必须为每个Bitronix实例配置唯一ID。 默认情况下,此ID是运行Bitronix的计算机的IP地址。 要确保生产中的唯一性,应为应用程序的每个实例配置spring.jta.transaction-manager-id属性,并使用不同的值。

4.17.3 使用Java EE托管事务管理器

如果将Spring Boot应用程序打包为war或ear文件并将其部署到Java EE应用程序服务器,则可以使用应用程序服务器的内置事务管理器。 Spring Boot尝试通过查看常见的JNDI位置(java:comp/UserTransaction,java:comp/TransactionManager等)来自动配置事务管理器。 如果使用应用程序服务器提供的事务服务,通常还需要确保所有资源都由服务器管理并通过JNDI公开。 Spring Boot尝试通过在JNDI路径(java:/JmsXA或java:/XAConnectionFactory)中查找ConnectionFactory来自动配置JMS,并且可以使用spring.datasource.jndi-name属性来配置DataSource。

4.17.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;

4.17.5 支持替代嵌入式事务管理器

XAConnectionFactoryWrapper和XADataSourceWrapper接口可用于支持备用嵌入式事务管理器。 接口负责包装XAConnectionFactory和XADataSource bean,并将它们公开为常规ConnectionFactory和DataSource bean,它们透明地注册分布式事务。 DataSource和JMS自动配置使用JTA变体,前提是您有一个JtaTransactionManager bean和在ApplicationContext中注册的相应XA包装bean。

BitronixXAConnectionFactoryWrapper和BitronixXADataSourceWrapper提供了如何编写XA包装器的很好示例。