Spring Boot通过Atomkos或Bitronix的内嵌事务管理器支持跨多个XA资源的分布式JTA事务,当部署到恰当的J2EE应用服务器时也会支持JTA事务。
当发现JTA环境时,Spring Boot将使用Spring的JtaTransactionManager
来管理事务。自动配置的JMS,DataSource和JPA beans将被升级以支持XA事务。你可以使用标准的Spring idioms,比如@Transactional
,来参与到一个分布式事务中。如果处于JTA环境,但仍想使用本地事务,你可以将spring.jta.enabled
属性设置为false
来禁用JTA自动配置功能。
Atomikos是一个非常流行的开源事务管理器,并且可以嵌入到你的Spring Boot应用中。你可以使用spring-boot-starter-jta-atomikos
Starter去获取正确的Atomikos库。Spring Boot会自动配置Atomikos,并将合适的depends-on
应用到你的Spring Beans上,确保它们以正确的顺序启动和关闭。
默认情况下,Atomikos事务日志将被记录在应用home目录(你的应用jar文件放置的目录)下的transaction-logs
文件夹中。你可以在application.properties
文件中通过设置spring.jta.log-dir
属性来定义该目录,以spring.jta.atomikos.properties
开头的属性能用来定义Atomikos的UserTransactionServiceIml
实现,具体参考AtomikosProperties javadoc。
注 为了确保多个事务管理器能够安全地和相应的资源管理器配合,每个Atomikos实例必须设置一个唯一的ID。默认情况下,该ID是Atomikos实例运行的机器上的IP地址。为了确保生产环境中该ID的唯一性,你需要为应用的每个实例设置不同的spring.jta.transaction-manager-id
属性值。
Bitronix是一个流行的开源JTA事务管理器实现,你可以使用spring-boot-starter-jta-bitronix
starter为项目添加合适的Birtronix依赖。和Atomikos类似,Spring Boot将自动配置Bitronix,并对beans进行后处理(post-process)以确保它们以正确的顺序启动和关闭。
默认情况下,Bitronix事务日志(part1.btm
和part2.btm
)将被记录到应用home目录下的transaction-logs
文件夹中,你可以通过设置spring.jta.log-dir
属性来自定义该目录。以spring.jta.bitronix.properties
开头的属性将被绑定到bitronix.tm.Configuration
bean,你可以通过这完成进一步的自定义,具体参考Bitronix文档。
注 为了确保多个事务管理器能够安全地和相应的资源管理器配合,每个Bitronix实例必须设置一个唯一的ID。默认情况下,该ID是Bitronix实例运行的机器上的IP地址。为了确保生产环境中该ID的唯一性,你需要为应用的每个实例设置不同的spring.jta.transaction-manager-id
属性值。
Narayana是一个流行的开源JTA事务管理器实现,目前只有JBoss支持。你可以使用spring-boot-starter-jta-narayana
starter添加合适的Narayana依赖,像Atomikos和Bitronix那样,Spring Boot将自动配置Narayana,并对你的beans后处理(post-process)以确保正确启动和关闭。
Narayana事务日志默认记录到应用home目录(放置应用jar的目录)的transaction-logs
目录下,你可以通过设置application.properties
中的spring.jta.log-dir
属性自定义该目录。以spring.jta.narayana.properties
开头的属性可用于自定义Narayana配置,具体参考NarayanaProperties。
注 为了确保多事务管理器能够安全配合相应资源管理器,每个Narayana实例必须配置唯一的ID,默认ID设为1
。为确保生产环境中ID唯一性,你可以为应用的每个实例配置不同的spring.jta.transaction-manager-id
属性值。
如果你将Spring Boot应用打包为一个war
或ear
文件,并将它部署到一个J2EE的应用服务器中,那你就能使用应用服务器内建的事务管理器。Spring Boot将尝试通过查找常见的JNDI路径(java:comp/UserTransaction
, java:comp/TransactionManager
等)来自动配置一个事务管理器。如果使用应用服务器提供的事务服务,你通常需要确保所有的资源都被应用服务器管理,并通过JNDI暴露出去。Spring Boot通过查找JNDI路径java:/JmsXA
或java:/XAConnectionFactory
获取一个ConnectionFactory
来自动配置JMS,并且你可以使用spring.datasource.jndi-name
属性配置你的DataSource
。
当使用JTA时,primary JMS ConnectionFactory
bean将能识别XA,并参与到分布式事务中。有些情况下,你可能需要使用non-XA的ConnectionFactory
去处理一些JMS消息。例如,你的JMS处理逻辑可能比XA超时时间长。
如果想使用一个non-XA的ConnectionFactory
,你可以注入nonXaJmsConnectionFactory
bean而不是@Primary
jmsConnectionFactory
bean。为了保持一致,jmsConnectionFactory
bean将以别名xaJmsConnectionFactor
来被使用。
示例如下:
// 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;
XAConnectionFactoryWrapper和XADataSourceWrapper接口用于支持可替换的内嵌事务管理器。该接口用于包装XAConnectionFactory
和XADataSource
beans,并将它们暴露为普通的ConnectionFactory
和DataSource
beans,这样在分布式事务中可以透明使用。Spring Boot将使用注册到ApplicationContext
的合适的XA包装器及JtaTransactionManager
bean自动配置你的DataSource和JMS。
BitronixXAConnectionFactoryWrapper和BitronixXADataSourceWrapper提供很好的示例用于演示怎么编写XA包装器。