Suppose you want to develop a high-volume transaction processing system in Java/J2EE. How would you do it? Most people would say: don’t use JTA/XA transactions because they kill performance. Wrong. And they would also say: use an appserver to scale. Again, they couldn’t be more wrong.
Here is the magic recipe on how we build systems with virtually unlimited scalability at Atomikos:
- Kick out your appserver as soon as you can, as explained here. J2EE is not limited to an appserver. J2EE is a set of APIs. The appserver ties these APIs to a programming model that almost nobody needs. Conclusion: drop the latter.
- Use a persistent JMS queue to store transaction requests. This allows easy load-balancing and provides crash resilience for ongoing requests. It also de-couples the clients from the transaction processing system.
- Use ExtremeTransactions to process the requests (stored in JMS). This allows for reliable, exactly-once message processing as outlined here. Make sure to use the supplied JMS and JDBC drivers!
- To add more power, just add a second VM (process) on a separate CPU.
- Repeat until performance is high enough.
You will reach the required performance because of the intra-VM nature of each process you add. The only potential bottlenecks are your own database or JMS backend. So scaling comes down to scaling your backends, which is much simpler than scaling your application itself (which has already been done in a natural way as outlined above).
So don’t let anybody fool you: transactions do scale - even without limits!.