You can now use Atomikos with Spring Boot 3.4.
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 moreThis 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.
You can now just use the new starter for your project.
You now get a meaningful error message when the JDBC driver does not return a valid connection.
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".
None.
We now avoid useless XA connection refreshing on shutdown.
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.
None.
| Severity: | 4 |
|---|---|
| Affected version(s): | 6.0.112 |
Your getConnection requests now get the (new) connections they deserve.
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.
None.
| Severity: | 4 |
|---|---|
| Affected version(s): | 6.0.x, 5.0.x |
You can now safely repeat JNDI lookups for our JDBC and JMS factories bound in Tomcat's JNDI space.
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.
None.
We now require customers to install subscription files for production use, similar to what we do in 6.0.
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.You need to install 2 files as explained on the documentation page mentioned above. Note: development or testing use does not need subscription files.
We now help you find out about known vulnerable maven dependencies that your application is using.
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:
Starting in the near future, expect more and more "security updates" in that respect.
None.
| Severity: | 4 |
|---|---|
| Affected version(s): | 5.0.x |
Any spring.jta properties in Spring Boot should now be taken into account.
This has proven to confuse users, so we now take such spring.jta properties into account.
Any spring.jta properties in Spring Boot should now be taken into account.
| Severity: | 4 |
|---|---|
| Affected version(s): | 5.0.x |
You can now count on the property values from jta.properties to be taken into account even with Spring Boot.
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.
Your properties specified in jta.properties should now work.
| Severity: | 1/2/3/4 |
|---|---|
| Affected version(s): | 5.0.x |
AtomikosRestPort URL is not set (for transactions across remoting calls).
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.
None.
| Severity: | 4 |
|---|---|
| Affected version(s): | 5.0.x |
You can now use transitive readOnly remoting transactions in all cases.
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.
None.
| Severity: | 2 |
|---|---|
| Affected version(s): | 5.0.x |
You can now use @RequiresNew with imported transactions.
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:
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).
You should now be able to configure @RequiresNew on any service that needs it.
| Severity: | 4 |
|---|---|
| Affected version(s): | 5.0.x |
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.
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)
None.
Releases 6.0.110 and 6.0.111 offered a fairer way of growing the connection pool. This has been optimised further.
The two prior releases attempted to offer a fairer way of growing the connection pool, so a thread that requests an extra connection could also use it. However, there the algorithm was still not as good as it could be, because it did the following:
While this performed better than before, this still allowed for another thread to hijack the connection between steps 3 and 4.
We now changed this to the following:
The extra step 3 implies that no other thread can take the connection after step 4. Thus, Thread A is always able to use the new connection.
None.
| Severity: | 4 |
|---|---|
| Affected version(s): | 6.0.110 |
The Tomcat examples have been modified to user Docker, but this does not work on all platforms yet.
The Docker image generated to run the Tomcat examples contains a Java JDK that is not binary compatible with all platforms yet.
You can now benefit from reduced synchronisation overhead thanks to concurrent maps usage in our core classes.
om.atomikos.icatch.feature.207056 = true
This is enabled by default because we are confident it works better than before. If you experience problems after upgrading, set this to false...
You can now shift Kubernetes pods by starting a new pod while the old one is still terminating.
In Kubernetes environments pods might be terminated and shifted to other nodes. Because of this the configured log path might be in use if the old pod is about to terminate and the new one is starting up. To be able to use the same LogFileLock we now offer retry attempts for the new pod which is trying to acquire the lock.
You can now use the same JTA and JMS dependency versions of Spring Boot's rather than the ones we specify.
For Spring Boot 2 we used to specify a particular version for each of JTA and JMS. This would override the versions that Spring Boot prefers. We no longer do this.
None.
You can now check the examples for Hibernate 7.
We've added working samples for Hibernate 7.
| Severity: | 3 |
|---|---|
| Affected version(s): | 6.O.x, 5.0.x |
You can now expect more accurate exception messages when creating a JDBC statement fails
We used to have one generic exception message when a statement could not be created, each time suggesting a timeout of the transaction. This was confusing if the real reason was, for instance, the transaction having been marked for rollback only.
The code has been refined live this:
TxState state = ct.getState();
if (state == TxState.ACTIVE) {
ct.registerSynchronization(new JdbcRequeueSynchronization(this, ct));
} else if (state == TxState.MARKED_ABORT){
AtomikosSQLException.throwAtomikosSQLException("The transaction has been set to rollback-only");
} else {
AtomikosSQLException.throwAtomikosSQLException("The transaction has timed out - try increasing the timeout if needed");
}
None.
| Severity: | 3 |
|---|---|
| Affected version(s): | 6.O.x |
Interposed synchronisation instances are now called on regular rollback also.
None.
| Severity: | 3 |
|---|---|
| Affected version(s): | 6.0.x |
Getting a new connection is now more efficient.
None.
| Severity: | 4 |
|---|---|
| Affected version(s): | 5.O.x, 6.0.x |
The class AtomikosSQLException was not exposed as public in OSGi.
The class AtomikosSQLException was not exposed as public in OSGi because it was in an "internal" package. This class has been moved to a public package instead, so it can be used with OSGi.
You have to change the imports when your code references this exception.
| Severity: | 3 |
|---|---|
| Affected version(s): | 5.0.x, 6.0.x and prior (decorated) releases |
Timeout / rollback of a subtransaction no longer appears as a commit to the parent transaction.
Timeout with subsequent rollback of a subtransaction would interfere with a later commit of the parent transaction: the state handler for the subtransaction would erroneously reply with READONLY upon 2PC prepare. This would make it seem to the parent transaction as though commit may proceed. We've fixed this by checking for timeout upon prepare of a subtransaction. Most people are not using subtransaction functionality, but those who do will benefit from this fix.
None.
| Severity: | 3 |
|---|---|
| Affected version(s): | 5.0.x, 6.0.x and prior (decorated) releases |
We improved the way imported transactions are handled in the case of network timeouts - so it aligns with our concurrency model.
None.
| Severity: | 3 |
|---|---|
| Affected version(s): | 6.0.x |
Creating many JDBC statements no longer leads to high memory consumption.
For technical reasons we keep a "cached" collection of JDBC statements. Due to a bug, such statements were added multiple times to a list. We fixed this by:
None.
| Severity: | 3 |
|---|---|
| Affected version(s): | 5.0.x, 6.0.x |
We changed the use of a HashMap to a ConcurrentHashMap for pending request synchronisation instances.
None.
| Severity: | 3 |
|---|---|
| Affected version(s): | 4.0.x, 5.0.x, 6.0.x |
Interruptions during Spring Boot shutdown are now handled better by the connection pool.
Full details as disclosed in the original report:
We experienced a somewhat strange behaviour with Atomikos in a situation, where our application (Spring Boot) is shutting down while some threads are waiting for a connection. In this shutdown-situation, Spring Boot sends an 'interupt' to all running threads. The Atomikos ConnectionPool method 'waitForAtLeastOneAvailableConnection()' handles this InterruptedException by invoking the InteruptedExceptionHelper. This in turn logs the exception and re-interrupts the thread. This is the correct pattern to interrupt possible further waits in the call stack.
But the method does not leave the while-loop. This causes a loop for the remaining borrowConnectionTimeout, leading to a very large amount of exception logs.
None.
| Severity: | 4 |
|---|---|
| Affected version(s): | 6.0.x |
You can now use the Tomcat Jakarta functionality in the free trial download.
The relevant jar file for this was missing from the evaluation zip file. It has now been added.
| Severity: | 4 |
|---|---|
| Affected version(s): | 6.0.110 |
The Tomcat examples have been modified to user Docker, but this does not work on all platforms yet.
The Docker image generated to run the Tomcat examples contains a Java JDK that is not binary compatible with all platforms yet.
| Severity: | 2 |
|---|---|
| Affected version(s): | 6.0.110 |
The improvement shipped as part of release 6.0.110 contained a bug that cause race conditions on concurrent pool usage. This is no longer the case;
The improvement that made growing the pool fairer for concurrent waiting threads contained a bug that led to attempts to use the same connection in two different threads, leading to exceptions like this one:
com.atomikos.datasource.ResourceException: XA resource '5684df3b-2192-4bd1-ba12-91cb2d55edac': resume for XID 'xid://61653731323262342D336561322D343761362D613461632D373861393064643062616539:31302E3130312E31332E392E746D31343035303633' raised -6: the XA resource did not expect this command in the current context at com.atomikos.datasource.xa.XAResourceTransaction.resume(XAResourceTransaction.java:240) at com.atomikos.datasource.xa.session.BranchEnlistedStateHandler.<init>(BranchEnlistedStateHandler.java:42) at com.atomikos.datasource.xa.session.NotInBranchStateHandler.checkEnlistBeforeUse(NotInBranchStateHandler.java:46) at com.atomikos.datasource.xa.session.TransactionContext.checkEnlistBeforeUse(TransactionContext.java:58) at com.atomikos.datasource.xa.session.SessionHandleState.notifyBeforeUse(SessionHandleState.java:185) at com.atomikos.jdbc.internal.AtomikosJdbcConnectionProxy.enlist(AtomikosJdbcConnectionProxy.java:89) at com.atomikos.jdbc.internal.AtomikosJdbcConnectionProxy.updateTransactionContext(AtomikosJdbcConnectionProxy.java:62) at com.atomikos.jdbc.internal.AbstractJdbcConnectionProxy.prepareStatement(AbstractJdbcConnectionProxy.java:65) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at com.atomikos.util.DynamicProxySupport.callProxiedMethod(DynamicProxySupport.java:167) at com.atomikos.util.DynamicProxySupport.invoke(DynamicProxySupport.java:121) at jdk.proxy3/jdk.proxy3.$Proxy235.prepareStatement(Unknown Source) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:262) at jdk.proxy3/jdk.proxy3.$Proxy232.prepareStatement(Unknown Source) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:153) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:183) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:155) at org.hibernate.sql.exec.spi.JdbcSelectExecutor.lambda$list$0(JdbcSelectExecutor.java:85) at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.executeQuery(DeferredResultSetAccess.java:231) at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.getResultSet(DeferredResultSetAccess.java:167) at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.advanceNext(JdbcValuesResultSetImpl.java:218) at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.processNext(JdbcValuesResultSetImpl.java:98) at org.hibernate.sql.results.jdbc.internal.AbstractJdbcValues.next(AbstractJdbcValues.java:19) at org.hibernate.sql.results.internal.RowProcessingStateStandardImpl.next(RowProcessingStateStandardImpl.java:66) at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:202) at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:33) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:209) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:83) at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:76) at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:65) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$2(ConcreteSqmSelectQueryPlan.java:137) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:381) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:303) at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:509) at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:427) at org.hibernate.query.Query.getResultList(Query.java:120) at org.springframework.data.jpa.repository.query.JpaQueryExecution$ExistsExecution.doExecute(JpaQueryExecution.java:315) at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:149) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:137) at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170) at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:169) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:148) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at datadog.trace.instrumentation.springdata.RepositoryInterceptor.invoke(RepositoryInterceptor.java:43) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) at jdk.proxy3/jdk.proxy3.$Proxy395.existsByRetailTaxpayerIdIn(Unknown Source) at .portfolio_management.taxpayer.PendingSyncService.hasTaxpayerPendingSync(PendingSyncService.java:89) at .portfolio_management.executionaware.evaluation.EvaluationJob$Runner.washGroupCanBeEvaluated(EvaluationJob.java:145) at xxx.portfolio_management.executionaware.evaluation.EvaluationJob$Runner.shouldRunJob(EvaluationJob.java:137) at xxx.portfolio_management.executionaware.evaluation.EvaluationJob$Runner.run_aroundBody0(EvaluationJob.java:113) at xxx.portfolio_management.executionaware.evaluation.EvaluationJob$Runner$AjcClosure1.run(EvaluationJob.java:1) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:67) at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:73) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:71) at xxx.portfolio_management.executionaware.evaluation.EvaluationJob$Runner.run(EvaluationJob.java:112) at xxx.portfolio_management.executionaware.evaluation.EvaluationJob$Runner.run(EvaluationJob.java:61) at xxx.dj.DelayedJobWorker.lambda$process$0(DelayedJobWorker.java:90) at xxx.telemetry.metrics.Metric.lambda$delayedJobTimer$0(Metric.java:25) at io.micrometer.core.instrument.AbstractTimer.record(AbstractTimer.java:187) at xxx.telemetry.metrics.Metric.lambda$delayedJobTimer$1(Metric.java:33) at io.micrometer.core.instrument.AbstractTimer.record(AbstractTimer.java:187) at xxx.telemetry.metrics.Metric.delayedJobTimer(Metric.java:33) at xxx.telemetry.metrics.Metric.delayedJobTimer(Metric.java:29) at xxx.dj.DelayedJobWorker.lambda$process$5(DelayedJobWorker.java:86) at xxx.telemetry.metrics.Metric.lambda$delayedJobTimer$0(Metric.java:25) at io.micrometer.core.instrument.AbstractTimer.record(AbstractTimer.java:187) at xxx.telemetry.metrics.Metric.lambda$delayedJobTimer$1(Metric.java:33) at io.micrometer.core.instrument.AbstractTimer.record(AbstractTimer.java:187) at xxx.telemetry.metrics.Metric.delayedJobTimer(Metric.java:33) at xxx.telemetry.metrics.Metric.delayedJobTimer(Metric.java:29) at xxx.dj.DelayedJobWorker.process(DelayedJobWorker.java:51) at xxx.dj.DelayedJobProcessor.lambda$claimAndSubmitJobs$0(DelayedJobProcessor.java:148) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: org.postgresql.xa.PGXAException: Connection is busy with another transaction at org.postgresql.xa.PGXAConnection.start(PGXAConnection.java:199) at com.atomikos.datasource.xa.XAResourceTransaction.resume(XAResourceTransaction.java:234) ... 94 more
None.
| Severity: | 4 |
|---|---|
| Affected version(s): | 6.0.110 |
The Tomcat examples have been modified to user Docker, but this does not work on all platforms yet.
The Docker image generated to run the Tomcat examples contains a Java JDK that is not binary compatible with all platforms yet.