36. 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 自动配置。

36.1 使用 AtomikosTransaction manager

Atomikos 是一种流行的开源事务 Management 器,可以嵌入到您的 Spring Boot 应用程序中。您可以使用spring-boot-starter-jta-atomikos Starter 引入适当的 Atomikos 库。 Spring Boot 将自动配置 Atomikos 并确保将适当的depends-on设置应用于您的 Spring bean,以正确启动和关闭订单。

默认情况下,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属性配置为不同的值。

36.2 使用 BitronixTransaction 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属性配置为不同的值。

36.3 使用 NarayanaTransaction manager

Narayana 是 JBoss 支持的流行的开源 JTA 事务 Management 器实现。您可以使用spring-boot-starter-jta-narayanaStarter 将适当的 Narayana 依赖项添加到您的项目中。与 Atomikos 和 Bitronix 一样,Spring Boot 将自动配置 Narayana 并对您的 bean 进行后处理,以确保启动和关闭 Sequences 正确。

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

Note

为了确保多个事务 Management 器可以安全地协调同一资源 Management 器,必须为每个 Narayana 实例配置唯一的 ID。默认情况下,此 ID 设置为1。为确保 Producing 的唯一性,应为应用程序的每个实例将spring.jta.transaction-manager-id属性配置为不同的值。

36.4 使用 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

36.5 混合 XA 和非 XA JMS 连接

使用 JTA 时,主要的 JMS ConnectionFactory bean 将了解 XA 并参与分布式事务。在某些情况下,您可能希望使用非 XA ConnectionFactory处理某些 JMS 消息。例如,您的 JMS 处理逻辑可能需要比 XA 超时更长的时间。

如果要使用非 XA ConnectionFactory,则可以注入nonXaJmsConnectionFactory bean 而不是@Primary jmsConnectionFactory bean。为了保持一致性,还使用 Bean 别名xaJmsConnectionFactory提供了jmsConnectionFactory bean。

For example:

// 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;

36.6 支持替代嵌入式事务 Management 器

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

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