On this page
36. Distributed Transactions with JTA
Spring Boot supports distributed JTA transactions across multiple XA resources using either an Atomikos or Bitronix embedded transaction manager. JTA transactions are also supported when deploying to a suitable Java EE Application Server.
When a JTA environment is detected, Spring’s JtaTransactionManager
will be used to manage transactions. Auto-configured JMS, DataSource and JPA beans will be upgraded to support XA transactions. You can use standard Spring idioms such as @Transactional
to participate in a distributed transaction. If you are within a JTA environment and still want to use local transactions you can set the spring.jta.enabled
property to false
to disable the JTA auto-configuration.
Atomikos is a popular open source transaction manager which can be embedded into your Spring Boot application. You can use the spring-boot-starter-jta-atomikos
Starter to pull in the appropriate Atomikos libraries. Spring Boot will auto-configure Atomikos and ensure that appropriate depends-on
settings are applied to your Spring beans for correct startup and shutdown ordering.
By default Atomikos transaction logs will be written to a transaction-logs
directory in your application home directory (the directory in which your application jar file resides). You can customize this directory by setting a spring.jta.log-dir
property in your application.properties
file. Properties starting spring.jta.atomikos.properties
can also be used to customize the Atomikos UserTransactionServiceImp
. See the AtomikosProperties
Javadoc for complete details.
Note | |
---|---|
To ensure that multiple transaction managers can safely coordinate the same resource managers, each Atomikos instance must be configured with a unique ID. By default this ID is the IP address of the machine on which Atomikos is running. To ensure uniqueness in production, you should configure the |
Bitronix is popular open source JTA transaction manager implementation. You can use the spring-boot-starter-jta-bitronix
starter to add the appropriate Bitronix dependencies to your project. As with Atomikos, Spring Boot will automatically configure Bitronix and post-process your beans to ensure that startup and shutdown ordering is correct.
By default Bitronix transaction log files (part1.btm
and part2.btm
) will be written to a transaction-logs
directory in your application home directory. You can customize this directory by using the spring.jta.log-dir
property. Properties starting spring.jta.bitronix.properties
are also bound to the bitronix.tm.Configuration
bean, allowing for complete customization. See the Bitronix documentation for details.
Note | |
---|---|
To ensure that multiple transaction managers can safely coordinate the same resource managers, each Bitronix instance must be configured with a unique ID. By default this ID is the IP address of the machine on which Bitronix is running. To ensure uniqueness in production, you should configure the |
Narayana is popular open source JTA transaction manager implementation supported by JBoss. You can use the spring-boot-starter-jta-narayana
starter to add the appropriate Narayana dependencies to your project. As with Atomikos and Bitronix, Spring Boot will automatically configure Narayana and post-process your beans to ensure that startup and shutdown ordering is correct.
By default Narayana transaction logs will be written to a transaction-logs
directory in your application home directory (the directory in which your application jar file resides). You can customize this directory by setting a spring.jta.log-dir
property in your application.properties
file. Properties starting spring.jta.narayana.properties
can also be used to customize the Narayana configuration. See the NarayanaProperties
Javadoc for complete details.
Note | |
---|---|
To ensure that multiple transaction managers can safely coordinate the same resource managers, each Narayana instance must be configured with a unique ID. By default this ID is set to |
If you are packaging your Spring Boot application as a war
or ear
file and deploying it to a Java EE application server, you can use your application servers built-in transaction manager. Spring Boot will attempt to auto-configure a transaction manager by looking at common JNDI locations (java:comp/UserTransaction
, java:comp/TransactionManager
etc). If you are using a transaction service provided by your application server, you will generally also want to ensure that all resources are managed by the server and exposed over JNDI. Spring Boot will attempt to auto-configure JMS by looking for a ConnectionFactory
at the JNDI path java:/JmsXA
or java:/XAConnectionFactory
and you can use the spring.datasource.jndi-name
property to configure your DataSource
.
When using JTA, the primary JMS ConnectionFactory
bean will be XA aware and participate in distributed transactions. In some situations you might want to process certain JMS messages using a non-XA ConnectionFactory
. For example, your JMS processing logic might take longer than the XA timeout.
If you want to use a non-XA ConnectionFactory
you can inject the nonXaJmsConnectionFactory
bean rather than the @Primary
jmsConnectionFactory
bean. For consistency the jmsConnectionFactory
bean is also provided using the bean alias xaJmsConnectionFactory
.
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;
The XAConnectionFactoryWrapper
and XADataSourceWrapper
interfaces can be used to support alternative embedded transaction managers. The interfaces are responsible for wrapping XAConnectionFactory
and XADataSource
beans and exposing them as regular ConnectionFactory
and DataSource
beans which will transparently enroll in the distributed transaction. DataSource and JMS auto-configuration will use JTA variants as long as you have a JtaTransactionManager
bean and appropriate XA wrapper beans registered within your ApplicationContext
.
The BitronixXAConnectionFactoryWrapper and BitronixXADataSourceWrapper provide good examples of how to write XA wrappers.