Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
When to use JTA / XA

When to use?

JTA/XA is a kind of system insurance against data corruption (and the resulting business losses). The most common use cases are: Processing JMS messages from a queue and inserting the results in a database: you don't want a crash to lose messages whose results are not yet stored in the database. Updating two or more legacy back-end systems in the same transaction In general, whenever you access more than one back-end system in the same transaction the use of JTA/XA is highly recommended. Otherwise, the risk of data loss or corruption is too high (and not necessarily visible!). Many programmers try to avoid the "overhead" of JTA/XA by programming application-specific recovery code (such as trying to handle duplicate requests, storing extra state in the database, etc). However, all these approaches are brittle (not reusable, application-specific, and hard to test). In the end, the perceived overhead of JTA/XA is often replaced by equivalent but buggy overhead at the application level.

A sample calculation shows the expected benefit of JTA/XA: suppose you are a bank and you have to handle 1 million transactions per day, and with an average value per transaction of 100 USD. This makes a total turnover of 100 million USD per day. If a system crash would cause as little as 1% data loss, then you would have a total cost of 1 million USD for a crash! In this scenario, JTA/XA clearly saves you a lot of money.

When not to use?

The table below shows some cases where you can consider not using JTA/XA, and some trade-offs. In all other cases, JTA/XA offers significant benefits in terms of reliability and simplicity.

Scenario Feasibility without JTA/XA JTA/XA benefits
At most one resource access Safe, although system locks may keep the transaction pending Infinite locks are impossible because XA propagates transaction timeouts to the resource
Multiple resource accesses, but in same back-end system Safe if you use the same connection for each access - sharing data between different accesses may require thread-local manipulation of the shared connection handle, and commit handling is complex Data sharing is handled by XA
Multiple queries in different back-end systems Possible, though global correctness is not guaranteed because there is no global transaction concept: your transaction may be reading values that never existed in that combination Correct reads in all cases because locks will be kept for the global transaction - avoiding interleaving effects with other, concurrent transactions
Many back-ends Not safe: only do this if you are willing to face data loss in case of a crash No data loss or corruption


All credits to Atomikos and the writer of this article, Guy Pardon. This is just a personal backup. For original article, please refer to:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment