跳到主要内容

使用 JTA 实现分布式事务

DeepSeek V3 中英对照 Distributed Transactions With JTA

Spring Boot 通过从 JNDI 中获取的事务管理器,支持跨多个 XA 资源的分布式 JTA 事务。

当检测到 JTA 环境时,Spring 的 JtaTransactionManager 会被用于管理事务。自动配置的 JMS、DataSource 和 JPA Bean 将升级为支持 XA 事务。你可以使用标准的 Spring 惯用法,例如 @Transactional,来参与分布式事务。如果你处于 JTA 环境中但仍想使用本地事务,可以将 spring.jta.enabled 属性设置为 false 以禁用 JTA 自动配置。

使用 Jakarta EE 托管事务管理器

如果你将 Spring Boot 应用程序打包为 warear 文件并部署到 Jakarta EE 应用服务器上,你可以使用应用服务器内置的事务管理器。Spring Boot 会通过查找常见的 JNDI 位置(如 java:comp/UserTransactionjava:comp/TransactionManager 等)来自动配置事务管理器。当使用应用服务器提供的事务服务时,通常还需要确保所有资源都由服务器管理并通过 JNDI 暴露。Spring Boot 会通过查找 JNDI 路径(如 java:/JmsXAjava:/XAConnectionFactory)上的 ConnectionFactory 来自动配置 JMS,并且你可以使用 spring.datasource.jndi-name 属性 来配置你的 DataSource

混合 XA 和非 XA JMS 连接

在使用 JTA 时,主要的 JMS ConnectionFactory bean 是支持 XA 的,并参与分布式事务。你可以直接将其注入到你的 bean 中,而无需使用任何 @Qualifier 注解。

import jakarta.jms.ConnectionFactory;

public class MyBean {

public MyBean(ConnectionFactory connectionFactory) {
// ...
}

}
java

在某些情况下,您可能希望使用非 XA 的 ConnectionFactory 来处理某些 JMS 消息。例如,您的 JMS 处理逻辑可能比 XA 超时时间更长。

如果你想使用非 XA 的 ConnectionFactory,可以使用 nonXaJmsConnectionFactory bean:

import jakarta.jms.ConnectionFactory;

import org.springframework.beans.factory.annotation.Qualifier;

public class MyBean {

public MyBean(@Qualifier("nonXaJmsConnectionFactory") ConnectionFactory connectionFactory) {
// ...
}

}
java

为了保持一致性,jmsConnectionFactory bean 也通过使用 bean 别名 xaJmsConnectionFactory 提供:

import jakarta.jms.ConnectionFactory;

import org.springframework.beans.factory.annotation.Qualifier;

public class MyBean {

public MyBean(@Qualifier("xaJmsConnectionFactory") ConnectionFactory connectionFactory) {
// ...
}

}
java

支持嵌入式事务管理器

XAConnectionFactoryWrapperXADataSourceWrapper 接口可用于支持嵌入式事务管理器。这些接口负责包装 XAConnectionFactoryXADataSource bean,并将它们作为常规的 ConnectionFactoryDataSource bean 暴露出来,这些 bean 会自动参与到分布式事务中。只要你在 ApplicationContext 中注册了 JtaTransactionManager bean 和适当的 XA 包装器 bean,DataSource 和 JMS 自动配置就会使用 JTA 变体。