38. JTA 的分布式事务

Spring Boot 通过使用AtomikosBitronix嵌入式事务 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-bitronixStarter 程序将适当的 Bitronix 依赖项添加到您的项目中。与 Atomikos 一样,Spring Boot 自动配置 Bitronix 并对您的 bean 进行后处理,以确保启动和关闭 Sequences 正确。

默认情况下,Bitronix 事务日志文件(part1.btmpart2.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 应用程序打包为warear文件并将其部署到 Java EE 应用程序服务器,则可以使用应用程序服务器的内置事务 Management 器。 Spring Boot 尝试通过查看常见的 JNDI 位置(java:comp/UserTransactionjava:comp/TransactionManager等)来自动配置事务 Management 器。如果使用应用程序服务器提供的事务服务,通常还需要确保所有资源都由服务器 Management 并通过 JNDI 公开。 Spring Boot 通过在 JNDI 路径(java:/JmsXAjava:/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 器

XAConnectionFactoryWrapperXADataSourceWrapper接口可用于支持其他嵌入式事务 Management 器。这些接口负责包装XAConnectionFactoryXADataSource bean 并将它们作为常规ConnectionFactoryDataSource bean 公开,它们透明地注册了分布式事务。数据源和 JMS 自动配置使用 JTA 变体,前提是您拥有JtaTransactionManager bean 和在ApplicationContext中注册了适当的 XA 包装 bean。

BitronixXAConnectionFactoryWrapperBitronixXADataSourceWrapper提供了有关如何编写 XA 包装程序的良好示例。