@vlad_mihalcea: A beginner's guide to JTA Transaction Type https://vladmihalcea.com/jta-transaction-type/…

X AI KOLs Timeline Tools

Summary

Vlad Mihalcea explains how the JTA transaction type works, including the 2PC protocol and how to use JTA with Spring for global transactions across multiple data sources such as PostgreSQL and Ehcache.

A beginner's guide to JTA Transaction Type https://t.co/woGAg3y312 https://t.co/vr3yfBZ7zT
Original Article
View Cached Full Text

Cached at: 07/31/26, 10:53 AM

A beginner’s guide to JTA Transaction Type

https://t.co/woGAg3y312 https://t.co/vr3yfBZ7zT


JTA Transaction Type - Vlad Mihalcea

Source: https://vladmihalcea.com/jta-transaction-type/

Introduction

In this article, we are going to analyze how the JTA transaction type works.

Since this is the default transaction type when using Jakarta EE or Java EE applications, it’s very important to understand how JTA transactions work, especially since Spring Boot or Spring applications useRESOURCE_LOCALtransactions instead.

JTA Transaction Type

When using the JTA transaction type, you can operate modifications across multiple data sources in an atomic global transaction that either commits all changes or rolls them back.

To understand how JTA transactions work, consider the following diagram that depicts a global JTA transaction modifying both a PostgreSQL database and anEhcacheinstance:

JTA Transaction Type

JTA Transaction Type

  1. The application controls the transaction scope via theUserTransactioninterface.
  2. To participate in a global JTA transaction, a resource must implement theXAResourceinterface, which provides theprepare,commit, androllbackmethods that will be called by the JTA transaction manager based on the2PC (Two-Phase Commit) protocol. Our application enlists theEhcacheXAResourceto coordinate the transaction outcome for the Ehcache-related changes and thePGXAConnectionto commit or roll back the changes that were done in the PostgreSQL database.
  3. The application makes changes to the PostgreSQL database and to Ehcache and callscommiton theUserTransaction.
  4. The transaction manager will callprepareon eachXAResourceso they can vote on the transaction outcome. This is the first phase of the 2PC protocol that allows the enlisted resources to achieve consensus.
  5. If all resources agree to commit the transaction, thecommitmethod will be called on eachXAResource, and the changes operated by this JTA global transaction will become durable.

Using the JTA Transaction Type with Spring

The JPA specification defines two transaction types you could choose from: JTA and RESOURCE_LOCAL. By default, Jakarta EE and Java EE applications use the JTA transaction type, while Spring Boot uses the RESOURCE_LOCAL transaction type.

To use JTA in a Spring application, you would need a specific bean configuration.

First, you will have to create an instance of the JTAXADataSourceinterface. For PostgreSQL, we can use thePGXADataSource. Unlike the more common JDBCDataSource, theXADataSourcecan provide us with theXAResourcethat can be enlisted in a JTA global transaction.

However, since most data access frameworks operate with the JDBCDataSource, we will have to wrap thePGXADataSourceand return an instance of theDataSourceinterface, as illustrated by the following bean configuration:

@Bean
public DataSource dataSource() {
    try {
        PGXADataSource dataSource = new PGXADataSource();
        dataSource.setUrl(jdbcUrl);
        dataSource.setUser(jdbcUser);
        dataSource.setPassword(jdbcPassword);
⠀
        XARecoveryModule xaRecoveryModule = new XARecoveryModule();
        GenericXADataSourceWrapper wrapper = 
            new GenericXADataSourceWrapper(xaRecoveryModule);
        return wrapper.wrapDataSource(dataSource);
    } catch (Exception e) {
        throw new IllegalStateException(e);
    }
}

We can then pass theDataSourceto the JPAEntityManagerFactoryvia the SpringLocalContainerEntityManagerFactoryBeanconfiguration:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
    emf.setJtaDataSource(dataSource());
    emf.setPackagesToScan(packagesToScan());
⠀
    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    emf.setJpaVendorAdapter(vendorAdapter);
    emf.setJpaProperties(additionalProperties());
    return emf;
}

Afterward, we will have to create an instance of theJtaTransactionManagerso that the Spring@Transactionalmethods can use JTA transactions.

However, the SpringJtaTransactionManageris not really a standalone JTA transaction manager, likeNarayanaorAtomikos. Instead, theJtaTransactionManageris simply an instance of theAbstractPlatformTransactionManagerthat can work with the SpringTransactionInterceptorAspect, which is responsible for managing the declarative@Transactionalmethods.

Therefore, when creating the SpringJtaTransactionManagerinstance, we need to provide an instance of the standalone JTA transaction manager that implements the Jakarta Transactions specification.

If you are using Narayana, the Spring bean configuration is going to look like this:

@Bean
public JtaTransactionManager transactionManager() {
    JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
    jtaTransactionManager.setTransactionManager(jtaTransactionManager());
    jtaTransactionManager.setUserTransaction(jtaUserTransaction());
    jtaTransactionManager.setAllowCustomIsolationLevels(true);
    return jtaTransactionManager;
}

@Bean
public TransactionManagerImple jtaTransactionManager() {
    TransactionManagerImple transactionManager = new TransactionManagerImple();
    return transactionManager;
}

@Bean
public UserTransactionImple jtaUserTransaction() {
    UserTransactionImple userTransactionManager = new UserTransactionImple();
    return userTransactionManager;
}

If you enjoyed this article, I bet you are going to love myBookandVideo Coursesas well.

Conclusion

JTA transactions are needed if you have to operate changes on multiple data sources in an atomic fashion.

While theRESOURCE\_LOCALtransaction type can manage a single JDBCConnection, JTA allows you to span the transaction boundaries over multiple resources, such as database connections, JMS queues, or caches.

Vlad Mihalcea Consulting

Hypersistence Optimizer rocks!

Similar Articles

Postgres by Example

Hacker News Top

A hands-on introduction to PostgreSQL using annotated SQL examples, covering basics to advanced topics.

How PgBouncer Works

Lobsters Hottest

A detailed technical guide explaining how PgBouncer works as a PostgreSQL connection pooler, covering its pooling modes, production deployment, and common pitfalls.

All you need is PostgreSQL

Lobsters Hottest

A detailed guide on using PostgreSQL as a single database to handle all aspects of a financial application, including schema design, state machines, triggers, and performance optimization.