Here is the answer: because with microservices and cloud, people think they no longer have access to the technology that has been around for decades: a distributed transaction manager. (We know, even many experts believe this).
Typically part of every application server, such a transaction manager takes care of rollback across resources (so you don’t need Sagas) and reliable message delivery (so eventual consistency is automatic).
But application servers are disappearing because they are neither agile, nor cloud-friendly nor microservice-friendly. So what can one do?
Enter Atomikos: we have redesigned the essence of the application server to be lightweight and embeddable, so you can get started with microservices and cloud without needing complex patterns like Sagas or eventual consistency. Thanks to our connection pools and transaction manager, you get all the reliability of an application server - but embedded in your microservice applications and deployed to your cloud platform.
From now on, your microservice transactions are as easy as adding the @Transactional annotation on your services. Exactly-once messaging is super easy because a transaction manager automatically avoids message loss and/or duplicate message processing.We offer out-of-the-box integration with the most popular Java runtimes like Spring (Boot) and Tomcat.
Did we mention that we have fine-tuned performance? With our smart batching technology, your processing can even be faster than before. And it’s elastic too, for dynamic scaling.
Join numerous banks and insurance companies worldwide and find out why Gartner has named us a cool vendor.
You can now use Hazelcast 4 with our JTA/XA transactions, via an additional module "transactions-hazelcast4". This was required due to breaking API changes that were introduced in Hazelcast 4.
When using the prior Hazelcast integration (made for Hazelcast 3, not 4) you would get the following exception when trying to configure a JTA/XA enabled HazelcastInstance:
java.lang.UnsupportedOperationException: Client config object only supports adding new data structure configurations at com.hazelcast.client.impl.clientside.ClientDynamicClusterConfig.getLicenseKey(ClientDynamicClusterConfig.java:897) at com.hazelcast.config.ConfigXmlGenerator.generate(ConfigXmlGenerator.java:129) at com.atomikos.hazelcast.HazelcastTransactionalResource.<init>(HazelcastTransactionalResource.java:23) at com.atomikos.hazelcast.AtomikosHazelcastInstance.<init>(AtomikosHazelcastInstance.java:31) at com.atomikos.hazelcast.AtomikosHazelcastInstanceFactory.createAtomikosInstance(AtomikosHazelcastInstanceFactory.java:17) at ...
| Severity: | 4 |
|---|---|
| Affected version(s): | 5.0.104 |
When setting recycleActiveConnectionsInTransaction=true, you can now reuse connections more flexibly.
Consider the following use case with recycleActiveConnectionsInTransaction enabled:
With recycleActiveConnectionsInTransaction=true, c1 will be the same connection instance as c2.
So after method bar() closes c2, c1 will also be closed and this caused errors like these in step 4 of method foo():
The underlying XA session is closed
at com.atomikos.jdbc.internal.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:29)
at com.atomikos.jdbc.internal.AtomikosJdbcConnectionProxy.enlist(AtomikosJdbcConnectionProxy.java:108)
at com.atomikos.jdbc.internal.AtomikosJdbcConnectionProxy.updateTransactionContext(AtomikosJdbcConnectionProxy.java:61)
at com.atomikos.jdbc.internal.AbstractJdbcConnectionProxy.prepareStatement(AbstractJdbcConnectionProxy.java:64)
at sun.reflect.GeneratedMethodAccessor228.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.atomikos.util.DynamicProxySupport.callProxiedMethod(DynamicProxySupport.java:162)
at com.atomikos.util.DynamicProxySupport.invoke(DynamicProxySupport.java:116)
at com.sun.proxy.$Proxy801.prepareStatement(Unknown Source)
None.
You can now allow recycling of active JDBC/XA pooled connections within the same transaction, before they are "closed" by the application. This means that certain deadlock scenarios can be avoided.
Imagine the following use case:
Before this feature, step 4 would return a different physical connection from the pool. This would trigger a new XA branch, with unspecified isolation (locking) behaviour with respect to any updates performed via the connection in step 2. This could even cause deadlocks.
Therefore, people have asked us to allow for step 4 to reuse the same connection, c1. You can now enable this new behaviour by callingsetRecycleActiveConnectionsInTransaction(true) on the AtomikosDataSourceBean.
A new, optional setter on our datasource. The default is false for backward compatibility.
Read this for our experience with running on JDK 11...