Spring Boot supports distributed JTA transactions across multiple XA resources by using an Atomikos 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
is used to manage transactions.
Auto-configured JMS, DataSource, and JPA beans are 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 configprop: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 auto-configures Atomikos and ensures that appropriate depends-on
settings are applied to your Spring beans for correct startup and shutdown ordering.
By default, Atomikos transaction logs are written to a transaction-logs
directory in your application’s home directory (the directory in which your application jar file resides).
You can customize the location of this directory by setting a configprop:spring.jta.log-dir[] property in your application.properties
file.
Properties starting with spring.jta.atomikos.properties
can also be used to customize the Atomikos UserTransactionServiceImp
.
See the {spring-boot-module-api}/jta/atomikos/AtomikosProperties.html[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 configprop:spring.jta.transaction-manager-id[] property with a different value for each instance of your application. |
If you package your Spring Boot application as a war
or ear
file and deploy it to a Java EE application server, you can use your application server’s built-in transaction manager.
Spring Boot tries to auto-configure a transaction manager by looking at common JNDI locations (java:comp/UserTransaction
, java:comp/TransactionManager
, and so on).
If you use a transaction service provided by your application server, you generally also want to ensure that all resources are managed by the server and exposed over JNDI.
Spring Boot tries to auto-configure JMS by looking for a ConnectionFactory
at the JNDI path (java:/JmsXA
or java:/XAConnectionFactory
), and you can use the configprop:spring.datasource.jndi-name[] property to configure your DataSource
.
When using JTA, the primary JMS ConnectionFactory
bean is XA-aware and participates in distributed transactions.
You can inject into your bean without needing to use any @Qualifier
:
link:{docs-java}/features/jta/mixingxaandnonxaconnections/primary/MyBean.java[role=include]
In some situations, you might want to process certain JMS messages by 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 the nonXaJmsConnectionFactory
bean:
link:{docs-java}/features/jta/mixingxaandnonxaconnections/nonxa/MyBean.java[role=include]
For consistency, the jmsConnectionFactory
bean is also provided by using the bean alias xaJmsConnectionFactory
:
link:{docs-java}/features/jta/mixingxaandnonxaconnections/xa/MyBean.java[role=include]
The {spring-boot-module-code}/jms/XAConnectionFactoryWrapper.java[XAConnectionFactoryWrapper
] and {spring-boot-module-code}/jdbc/XADataSourceWrapper.java[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 transparently enroll in the distributed transaction.
DataSource and JMS auto-configuration use JTA variants, provided you have a JtaTransactionManager
bean and appropriate XA wrapper beans registered within your ApplicationContext
.
The {spring-boot-module-code}/jta/atomikos/AtomikosXAConnectionFactoryWrapper.java[AtomikosXAConnectionFactoryWrapper] and {spring-boot-module-code}/jta/atomikos/AtomikosXADataSourceWrapper.java[AtomikosXADataSourceWrapper] provide good examples of how to write XA wrappers.