The Atomikos Blog

Archive

You are here: Blog

Saga vs Transactional Call: Which One Should You Really Use?
If you are building microservices, you have probably heard of the Saga pattern

16 Sep 2025 | Guy Pardon | Tech tips, Vision | ,

If you are building microservices, you have probably heard of the Saga pattern. Maybe you are even using it. After all, it is the default answer you will find on Stack Overflow and in most conference talks when people ask: How do I manage distributed transactions?

Synchronous microservices look great on paper.

They are easy to read, easy to debug, and they map perfectly to how we think: “I send a request, I get a reply.” No surprises, right?

Except when things go wrong. Which in distributed systems is most of the time.

ExtremeTransactions 6.0.114
Release notes for 6.0.114

08 Apr 2025 | Guy Pardon | Release notes

Feature211440
Improve micrometer metrics support for the pool usage: add getPercentageOfPoolCapacityUsed

You can now see the pool's percentage used (wrt its capacity) in our Micrometer support module.

Technical details

The ability to see the pool's percentage used (wrt its capacity) was already present in our JMX module, but not in our Micrometer support. This has now been added.

Changes impacting client API

None.

Bug214569
Fix pom dependency for Spring Boot 3.4 starter

Severity:4
Affected version(s):6.0.113

Description

You can now use the new Spring Boot 3.4 starter.

Technical details

The module transactions-spring-boot3.4-starter had a dependency on com.atomikos.transactions-spring-boot3, whereas it should have had a dependency on com.atomikos.transactions-spring-boot3.4. This has been fixed.

Changes impacting client API

None.

Bug212902
Improve error message on enlist / timeout

Severity:3
Affected version(s):6.0.x

Description

The error message on potential timeouts is now better.

Technical details

Some cases would report an error like "The transaction has timed out - try increasing the timeout if needed" when in fact the cause was a wrong state of the transaction.

This has been improved to also show state information:

"The transaction has potentially timed out (state: " + state + ") - try increasing the timeout if needed"

Changes impacting client API

None.

Bug212919
Improve thread-safety of CheckedExportingTransactionManager

Severity:2
Affected version(s):6.0.x

Description

The implementation of this class is now safer for multi-threaded use.

Technical details

The attribute pendingRequestSynchronisation used to be a HashMap and is now a ConcurrentHashMap.

Changes impacting client API

None.

Bug212877
Tomcat examples: fix port number in the README

Severity:4
Affected version(s):6.0.x

Description

The port number has been corrected in the README of the tomcat examples.

Technical details

The README file would contain port 8080 instead of 8888. This has been fixed.

Changes impacting client API

None.

Bug212878
Update tomcat examples to make docker include the latest release

Severity:4
Affected version(s):6.0.x

Description

The new Tomcat examples should now include the right Atomikos release.

Technical details

Due to an issue with maven plugins, the examples would not always ship the right Atomikos release. This has now been fixed.

Changes impacting client API

None.

Issue214480
Disable OSGi examples build

Severity:4
Affected version(s):6.0.x

Description

The OSGi examples are now skipped during the build.

Technical details

The OSGi examples used bundle dependencies hosted on a Spring repository site that has been discontinued. This made the build fail. Until we find a solution, we had to disable this module during the build (or releases would be blocked).

Issue215322
Zip files with example projects not uploaded correctly

Severity:4
Affected version(s):6.0.x

Description

The zip files with example projects failed to upload.

Technical details

When trying to download the example projects from the installation page(s) you will get "404 Not Found" errors. We are looking into it but decided not to let this block a maintenance release like this one.

ExtremeTransactions 6.0.113
Release notes for 6.0.113

27 Feb 2025 | Guy Pardon | Release notes

Feature211078
Add Spring Boot 3.4 starter

You can now use Atomikos with Spring Boot 3.4.

Technical details

Spring Boot 3.4 required a new starter project to make it work with Atomikos.

Attempting to use Spring Boot 3.4 with the older starter project would result in errors like this:

Caused by: java.lang.NoSuchMethodError: 'void org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers.customize(org.springframework.transaction.PlatformTransactionManager)'
  at com.atomikos.spring.AtomikosAutoConfiguration.lambda$transactionManager$0(AtomikosAutoConfiguration.java:84)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.ifAvailable(DefaultListableBeanFactory.java:2382)
  at com.atomikos.spring.AtomikosAutoConfiguration.transactionManager(AtomikosAutoConfiguration.java:84)
  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.lambda$instantiate$0(SimpleInstantiationStrategy.java:171)
  ... 50 more

This was due to Spring's removal of some deprecated methods in org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers. A new starter project was needed to fix this.

Changes impacting client API

You can now just use the new starter for your project.

Feature208173
Improve error message when JDBC driver does not return a valid connection

You now get a meaningful error message when the JDBC driver does not return a valid connection.

Technical details

When the JDBC driver does not return a valid connection, this would result in a cryptic exception like this:

java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "this.delegate" is null
                at com.atomikos.util.DynamicProxySupport.getClassLoadersToTry(DynamicProxySupport.java:195) ~[atomikos-util-6.0.112.jar:na]
                at com.atomikos.util.DynamicProxySupport.createDynamicProxy(DynamicProxySupport.java:189) ~[atomikos-util-6.0.112.jar:na]
                at com.atomikos.jdbc.internal.AtomikosNonXAPooledConnection.doCreateConnectionProxy(AtomikosNonXAPooledConnection.java:108) ~[transactions-jdbc-6.0.112.jar:na]
                at com.atomikos.jdbc.internal.AtomikosNonXAPooledConnection.doCreateConnectionProxy(AtomikosNonXAPooledConnection.java:35) ~[transactions-jdbc-6.0.112.jar:na]
                at com.atomikos.datasource.pool.AbstractXPooledConnection.createConnectionProxy(AbstractXPooledConnection.java:101) ~[transactions-jta-6.0.112.jar:na]
                at com.atomikos.datasource.pool.ConnectionPoolWithConcurrentValidation.concurrentlyTryToUse(ConnectionPoolWithConcurrentValidation.java:61) ~[transactions-jta-6.0.112.jar:na]
                at com.atomikos.datasource.pool.ConnectionPoolWithConcurrentValidation.retrieveFirstAvailableConnection(ConnectionPoolWithConcurrentValidation.java:43) ~[transactions-jta-6.0.112.jar:na]
                at com.atomikos.datasource.pool.ConnectionPool.retrieveFirstAvailableConnectionAndGrowPoolIfNecessary(ConnectionPool.java:140) ~[transactions-jta-6.0.112.jar:na]
                at com.atomikos.datasource.pool.ConnectionPool.findOrWaitForAnAvailableConnection(ConnectionPool.java:128) ~[transactions-jta-6.0.112.jar:na]
                at com.atomikos.datasource.pool.ConnectionPool.borrowConnection(ConnectionPool.java:119) ~[transactions-jta-6.0.112.jar:na]
                at com.atomikos.jdbc.internal.AbstractDataSourceBean.getConnection(AbstractDataSourceBean.java:375) ~[transactions-jdbc-6.0.112.jar:na]
                at com.atomikos.jdbc.AtomikosNonXADataSourceBean.getConnection(AtomikosNonXADataSourceBean.java:208) ~[transactions-jdbc-6.0.112.jar:na]

This has now been fixed: we now report that the "Driver didn't return a valid Connection".

Changes impacting client API

None.

Feature207950
Avoid unnecessary XA connection refresh on shutdown

We now avoid useless XA connection refreshing on shutdown.

Technical details

The following would happen upon shutdown, when for instance the JMS server was gone:

Failed to refresh XAResource
com.atomikos.datasource.ResourceException: Error in getting XA resource
        at com.atomikos.datasource.xa.jms.JmsTransactionalResource.refreshXAConnection(JmsTransactionalResource.java:83) ~[!/:?]
        at com.atomikos.datasource.xa.XATransactionalResource.refreshXAResource(XATransactionalResource.java:413) ~[!/:?]
        at com.atomikos.datasource.xa.XATransactionalResource.getXAResource(XATransactionalResource.java:227) ~[!/:?]
        at com.atomikos.datasource.xa.XATransactionalResource.isSameRM(XATransactionalResource.java:317) ~[!/:?]
        at com.atomikos.datasource.xa.XATransactionalResource.equals(XATransactionalResource.java:430) ~[!/:?]
        at java.util.Vector.indexOf(Vector.java:413) ~[?:1.8.0_381]
        at java.util.Vector.indexOf(Vector.java:387) ~[?:1.8.0_381]
        at java.util.Vector.removeElement(Vector.java:646) ~[?:1.8.0_381]
        at java.util.Vector.remove(Vector.java:804) ~[?:1.8.0_381]
        at com.atomikos.icatch.config.Configuration.removeResource(Configuration.java:263) ~[!/:?]
        at com.atomikos.jms.AtomikosConnectionFactoryBean.close(AtomikosConnectionFactoryBean.java:597) ~[!/:?]

This has been improved / fixed - we now avoid such refresh.

Changes impacting client API

None.

Bug208965
Connection pool: make waiting for connections fair(er)

Severity:4
Affected version(s):6.0.112

Description

Your getConnection requests now get the (new) connections they deserve.

Technical details

In our 6.0 release the connection pool grows via a separate background thread. When getConnection finds no available connection, it will start waiting for this thread to grow the pool and add a new connection to it.

The implementation was "unfair" in that a waiting getConnection request could (and would) see its new connection "hijacked" by a different, later getConnection request.

This has now been fixed.

Changes impacting client API

None.

Bug211208
Tomcat JNDI factory for JDBC and JMS: make it tolerate double lookups

Severity:4
Affected version(s):6.0.x, 5.0.x

Description

You can now safely repeat JNDI lookups for our JDBC and JMS factories bound in Tomcat's JNDI space.

Technical details

There was a race condition in our code that could lead to repeated initialisation of JNDI resources with the same name, like JDBC datasources or JMS connection factories.

This has now been fixed.

Changes impacting client API

None.

ExtremeTransactions 5.0.109
ExtremeTransactions 5.0.109 release notes

10 Oct 2024 | Guy Pardon | Release notes

Feature200360
Subscription files are now required for production use

Description

We now require customers to install subscription files for production use, similar to what we do in 6.0.

Technical details

We've had some bad experiences with subscriptions purchased via resellers / intermediaries, that were first used by a development team, then moved onto other teams in production without us being able to keep track. This has lead to unpleasant experiences for both our customers and ourselves.

For more details, see this documentation page.

Changes impacting client API

You need to install 2 files as explained on the documentation page mentioned above. Note: development or testing use does not need subscription files.

Feature201309
Detect vulnerable dependencies on classpath

Description

We now help you find out about known vulnerable maven dependencies that your application is using.

Technical details

With current hacker efforts moving more and more into the application stack via vulnerable open source dependencies, we notice customers are getting worried (or facing audits of their applications). Log4j, anyone?

Our approach has been two-fold:

  • We avoid 3rd party dependencies so you can't pull them in by accident, and
  • We now also detect known vulnerable 3rd party maven dependencies on your application's classpath

Starting in the near future, expect more and more "security updates" in that respect.

Changes impacting client API

None.

Bug197240
Allow spring.jta properties in Spring Boot starter

Severity:4
Affected version(s):5.0.x

Description

Any spring.jta properties in Spring Boot should now be taken into account.

Technical details

After the Spring Boot team contributed the source code for their Atomikos starter we thought it was safer to ignore any properties with the "legacy" prefix spring.jta.atomikos.properties (in your application.properties file for Spring Boot).

This has proven to confuse users, so we now take such spring.jta properties into account.

Changes impacting client API

Any spring.jta properties in Spring Boot should now be taken into account.

Bug197505
Avoid that defaults in the Spring Boot starter override jta.properties

Severity:4
Affected version(s):5.0.x

Description

You can now count on the property values from jta.properties to be taken into account even with Spring Boot.

Technical details

The Atomikos JTA properties implementation in our Spring Boot starter would define default values for many properties, meaning that their value specified jta.properties would not be taken into account. This has now been fixed.

Changes impacting client API

Your properties specified in jta.properties should now work.

Bug197362
Clarify message if rest port not set in client

Severity:1/2/3/4
Affected version(s):5.0.x

Description

You can now count on a better error message when the AtomikosRestPort URL is not set (for transactions across remoting calls).

Technical details

When the AtomikosRestPort URL was not set, the client template would report a misleading message saying that there is no transaction for the thread. Instead, the root cause is a URL that is missing - so we fixed that for you.

Changes impacting client API

None.

Bug197506
Support diamond case architectures for readOnly remoting

Severity:4
Affected version(s):5.0.x

Description

You can now use transitive readOnly remoting transactions in all cases.

Technical details

As outlined in this GitHub issue there was a problem with readOnly invocations when:

  • the same shared service was called over different paths, and
  • all invocations were readOnly

This is known as a "diamond case" because the invocation diagram looks like a diamond.

This issue has been fixed in the following way: our product will now avoid the readOnly optimisation in this specific scenario. This is still correct, at a minor performance overhead in the exotic cases where this does happen.

Changes impacting client API

None.

Bug197253
Suspend/resume should not change local sibling count

Severity:2
Affected version(s):5.0.x

Description

You can now use @RequiresNew with imported transactions.

Technical details

As explained in this GitHub issue, there were problems when a remote transaction was imported and then subsequently called local logic that was marked with @RequiresNew. As required by the specification of @RequiresNew, this would suspend any active transaction - and resume it later.

Our code had a side effect of suspend/resume that changed the local sibling count.

Sibling counts help detect orphaned invocations (and their transactional updates to persistent storage) that arise out of lost replies. For instance, consider this scenario with services A and B:

  1. A starts a transaction.
  2. A calls B as part of that transaction.
  3. B does work and returns a result.
  4. A does not receive the result due to a network timeout (so B now has an orphaned invocation).
  5. A tries again, so B performs the changes again and returns a new result (in the same transaction).
  6. A commits the transaction thinking it only updated B once.
  7. B commits the same transaction with two sets of updates.

This risk here is the different views of A and B regarding the scope of the transaction: A thinks it commits one update to B, whereas B commits two different updates. This can be a problem for data consistency, so we avoid this by keeping sibling counts at B and A. A constructs its sibling count picture with each result it actually receives with its replies from A. Before commit, A passes on the "count" it has for invocations at B, and if B finds that there is no match then it refuses to commit.

This would avoid the problem outlined above, because in step 4 service A will miss a count, so in step 6 service A will pass a count of 1 for service B, whereas B will see 2 and refuses the commit process.

In short, sibling counts have their purpose. However due to a bug, this was affected by a suspend/resume at service B (when it has @RequiresNew logic inside).

Changes impacting client API

You should now be able to configure @RequiresNew on any service that needs it.

Bug211208
Avoid init-ing connection factory twice or more on Tomcat JNDI lookups

Severity:4
Affected version(s):5.0.x

Description

You should now be able to perform any number of JNDI lookups in Tomcat without getting warnings about the resource already existing with the same name.

Technical details

During JNDI lookups, Tomcat applications would sometimes get warnings like below due to a race condition. This has been fixed.

WARNING: Cannot initialize AtomikosConnectionFactoryBean
java.lang.IllegalStateException: Another resource already exists with name XAConnectionFactory - pick a different name
      at com.atomikos.icatch.config.Configuration.addResource(Configuration.java:241)
      at com.atomikos.jms.AtomikosConnectionFactoryBean.doInit(AtomikosConnectionFactoryBean.java:440)
      at com.atomikos.jms.AtomikosConnectionFactoryBean.init(AtomikosConnectionFactoryBean.java:354)
      at com.atomikos.jms.AtomikosConnectionFactoryBean.createConnection(AtomikosConnectionFactoryBean.java:620)

Changes impacting client API

None.

Corporate Information

Atomikos Corporate Headquarters
Hoveniersstraat, 39/1, 2800
Mechelen, Belgium

Contact Us

Copyright 2026 Atomikos BVBA | Our Privacy Policy
This page was cached on 02 Apr 2026 - 17:51.
By using this site you agree to our cookies. More info. That's Fine