The Atomikos Blog
You are here: Blog

ExtremeTransactions 6.0
Support for both javax and jakarta EE

06 May 2023 | Guy Pardon | Release notes

Added support for Jakarta EE, Spring Boot 3 and Hibernate 6.

TransactionsEssentials 6.0
Release notes for the 6.0 release

13 Jan 2023 | Guy Pardon | Release notes

Upgrading from 5.0 to 6.0

This release was very hard to do. Not because we wanted many new features included (there are not that many, actually), but rather because it was a balancing act between stability / backwards compatibility and new "breaking change" emerging platforms (specifically: Spring Boot 3, Hibernate 6 and their dependencies on JakartaEE and very recent Java versions).

We think we did a good job: just like the previous release 5.0, this new release can run on "good old" Java 8 for most modules, except for Spring Boot 3 integration (which requires Java 17 as per Spring Boot) and Hibernate 6. So if your application worked with release 5.0 then it should still work, provided that you do the following:

Add extra dependencies explicitly to your POM

We now support both javax and jakarta namespaces for the Java enterprise APIs, by offering regular jars as well as "jakarta" jars (with the corresponding classifier in the jar names). These jakarta jars are generated at build time with the Eclipse transformer utility.

In order to do this, we had to break the transitive dependency mechanism (which, incidentally, also avoids pulling in vulnerable 3rd party code libs). So: except for Spring Boot 3 apps, this means that you will now have to add the following dependency to your pom file (or you risk facing ClassNotFoundExceptions):

The traditional javax style

    <dependency>
         <groupId>com.atomikos</groupId>
         <artifactId>transactions-jta</artifactId>
         <version>6.0.109</version> <!-- Commercial, for open source use version 6.0.0 -->
    </dependency>

     <dependency>
         <groupId>jakarta.jms</groupId>
         <artifactId>jakarta.jms-api</artifactId> 
         <!-- NOTE: despite "jakarta" in the name, this version is still a javax jar -->
         <version>2.0.3</version>
     </dependency>

     <dependency>
         <groupId>javax.transaction</groupId>
         <artifactId>jta</artifactId>
         <version>1.1</version>
      </dependency>

The new jakarta style

      <dependency>
         <groupId>com.atomikos</groupId>
         <artifactId>transactions-jta</artifactId>
         <version>6.0.109</version> <!-- Commercial, for open source use version 6.0.0 -->
         <classifier>jakarta</classifier>
      </dependency>

      <dependency>
         <groupId>jakarta.jms</groupId>
         <artifactId>jakarta.jms-api</artifactId>
         <version>3.1.0</version>
      </dependency>

      <dependency>
         <groupId>jakarta.transaction</groupId>
         <artifactId>jakarta.transaction-api</artifactId>
         <version>2.0.1</version>
      </dependency>

Override the new JMS behaviour to revert to prior release behaviour

We now support JMS 2. This required some changes to the JMS session creation behaviour, so if you rely on the "old" JMS behaviour then set the following property on the AtomikosConnectionFactoryBean:

     AtomikosConnectionFactoryBean cf = new AtomikosConnectionFactoryBean();
     // 1 sets behaviour like in releases 3.9-5.0, 0 sets behaviour like in releases pre-3.9
     cf.setSessionCreationMode(1); 

For more details, see the javadoc of the AtomikosConnectionFactoryBean class.

Drop any reapTimeout property

We've removed reap functionality from the pool, so remove any reapTimeout property in your datasource or connection factory config.

Detailed release notes

If you like the nitty gritty details, then the following sections are for you!

Feature199869
Spring Boot 3 Starter

We added a starter for Spring Boot 3.

Technical details

Spring Boot 3 has made a "big bang" upgrade to Jakarta EE and Java 17, with all complications involved. You can now use Atomikos with Spring Boot 3 by means of our new Spring Boot 3 starter module.

Changes impacting client API

Spring Boot 3 requires Java 17 or higher, plus all JakartaEE libraries (and for course Atomikos releases 6.0 or higher). Note that this means you will also need JakartaEE JMS drivers, and JakartaEE persistence providers. Hurray.

You need the following dependency to use Spring Boot 3:

      <dependency>
         <groupId>com.atomikos</groupId>
         <artifactId>transactions-spring-boot3-starter</artifactId>
         <version>6.0.109</version>
      </dependency>

For the JakartaEE JMS and JTA APIs: we've added those to the Spring Boot 3 starter module already - so you don't have to bother.

Feature197500
Support JakartaEE libraries and packages

Description

We now also support JakartaEE (in addition to the "old" JEE with javax namespaces).

Technical details

All relevant modules are now available in both a traditional variant and a JakartaEE variant, the latter generated with the Eclipse transformer utility during the build. JakartaEE jars carry the same name as their traditional counterparts, but have the additional classifier "jakarta" in the jar file name to distinguish them.

The choice for this strategy was heavily driven by our desire to still support Java 8 applications that can't upgrade to Java 17 or JakartaEE right now.

The previous statement probably deserves some explanation: after some initial attempts it was painfully clear to us that upgrading from Java 8 to Java 17 is nothing short of a nightmare.

[Oh and by the way, we figure that this is the reason why extended support for Java 8 is available until 2030, the longest of all Java versions at the time of publication. Yes, that means Java 8 should be supported for longer than Java 17 - go figure that!]

Our chosen approach should allow existing installations to upgrade to our 6.0 release without the need to upgrade to JakartaEE and/or Java 17 at the same time.

Past experience with our customers has shown that even a "simple" upgrade from Java 6 to Java 8 can be a huge roadblock - especially if the development team is gone and only operations teams are left. So we prefer to keep upgrading a seamless and straightforward process, without requiring needless Java updates at the same time. We are sure that you will appreciate that.

The "downside" of this choice is that you can no longer count on transitive dependencies as much as you did, because many modules now have 2 variants available (and hence the transitive dependencies would not necessarily match the right variant). While this may seem a disadvantage, it actually increases security because there are no longer transitive dependencies on 3rd party jars either (so you avoid pulling in vulnerabilities).

So: you have to add some dependencies manually that were transitive before. But the effort required is significantly lower than the effort it would take to upgrade your code base towards Java 17 and JakartaEE all at once.

Changes impacting client API

As explained in the upgrade section above: you need to declare some extra dependencies. Also, you have to be careful to use the right combination of Jakarta-enabled jars in your application. To this end, we have defined BOM files that list all the jars designed to work together:

  • transactions-essentials versus transactions-essentials-jakarta
  • extreme-transactions versus extreme-transactions-jakarta

You can check these BOMs for inspiration on which jars to use / combine in your application. If you are curious where to find them: check groupId=com.atomikos and artifactId=name_of_BOM_file.

Feature199608
Hibernate 6 support

Description

You can now easily use Hibernate 6 in combination with our product!

Technical details

Hibernate 6 is also in the JakartaEE camp, so of course you need JakartaEE support to be able to use it. Well, as we've explained above: we have done just that.

To use Hibernate 6, it suffices to use transactions-hibernate4 in the jakarta flavour.

For a working sample: check the supplied examples project called examples-hibernate6 or see the summary POM snippet below.

Changes impacting client API

No real changes are needed, but you do have to add the correct POM dependencies:

      <dependency>
         <groupId>com.atomikos</groupId>
         <artifactId>transactions-hibernate4</artifactId>
         <version>6.0.109</version>
         <classifier>jakarta</classifier>
      </dependency>
      <dependency>
         <groupId>com.atomikos</groupId>
         <artifactId>transactions-jdbc</artifactId>
         <version>6.0.109</version>                                              
         <classifier>jakarta</classifier>
      </dependency>
      <dependency>
         <groupId>com.atomikos</groupId>
         <artifactId>transactions-jta</artifactId>
         <version>6.0.109</version>
         <classifier>jakarta</classifier>
      </dependency>
      <dependency>
         <groupId>jakarta.transaction</groupId>
         <artifactId>jakarta.transaction-api</artifactId>
         <version>2.0.1</version>
      </dependency>
      <dependency>
         <groupId>jakarta.persistence</groupId>
         <artifactId>jakarta.persistence-api</artifactId>
         <version>3.1.0</version>
      </dependency>

Of course, you also need the Hibernate 6 dependencies themselves - but we'll leave that up to you…

Feature85601
JMS 2.0 support

Description

We now have (minimal) support for JMS 2.0.

Technical details

As required by JakartaEE and Spring Boot 3, we needed some support for JMS 2.0. For the sake of releasing on time, this support is only partial: we do not yet support the new JMSContext API. Spring Boot 3 does not seem to need it, so that should be fine for now. Attempting to call any of the createContext methods on the AtomikosConnectionFactoryBean will throw UnsupportedOperationException.

Changes impacting client API

Session creation behaviour has changed due to the clarification of session creation behaviour in JMS 2.0 (which is incompatible with what we had in prior releases). As you can see in the table below, the differences are in the combined interpretation of:

  • a JTA transaction being present on the calling thread or not,
  • the value set for localTransactionMode and
  • the value of the sessionTransacted flag when creating a session.

Prior to JMS 2.0, session creation had some fuzzy border cases where the interpretation was left to the party implementing the specs (like Atomikos). In JMS 2.0 this has been addressed. Needless to say, the probably of a perfect match with our interpretation was next to zero - so we had to make some changes.

To preserve compatibility your instances of AtomikosConnectionFactoryBean now offer an extra method setSessionCreationMode(int mode) which changes behaviour as described below. The default is value 2 (JMS 2.0) so for compatibility with 5.0, try value 1. For compatibility with pre-3.9 installations, try value 0.

SessionCreationMode.JMS_2_0 (the default as of release 6.0), resolving to constant value 2
existing JTA transaction for thread localTransactionMode resulting session
true ignored XA session
false false XA session
false true non-XA session according to sessionTransacted/acknowledgeMode parameters
SessionCreationMode.PRE_6_0 (optional, for backward compatibility) - resolving to constant value 1
localTransactionMode sessionTransactedFlag resulting session
false ignored XA session
true ignored non-XA session according to sessionTransacted/acknowledgeMode parameters
SessionCreationMode.PRE_3_9 (optional, for backward compatibility and equivalent to ignoreSessionTransactedFlag = false) - resolving to constant value 0
localTransactionMode sessionTransactedFlag resulting session
false true XA session
other other non-XA session according to sessionTransacted/acknowledgeMode parameters

You can also find this in the javadoc of the AtomikosConnectionFactoryBean.

Feature20711
Support for TransactionSynchronizationRegistry

Description

We now offer an implementation of TransactionSynchronizationRegistry defined in the more recent JTA specifications.

Technical details

You can use an instance of com.atomikos.icatch.jta.TransactionSynchronizationRegistryImp contained in module transactions-jta.jar.

Unless you are a vendor of persistence providers, you probably won't ever need this class so we'll keep the explanation to a minimum - since vendors of persistence providers already know all there is to know.

Changes impacting client API

An extra class available in our distribution, for you to use if you want to.

Feature199530
Make the transaction template thread-safe

Description

Instances of com.atomikos.icatch.jta.template.TransactionTemplate are now tread-safe.

Technical details

The first implementations of our template were not intended for threaded use cases. Based on customer feedback, we have changed that - so you can now reuse the same instance in different threads - just like Spring's template.

Changes impacting client API

Instead of having to create multiple template instances, you can now reuse the same instance in different places of your code base. This should simplify your configuration and code base.

Feature192016
Better support for borrowConnection timeouts in the pool

Description

We've improved the pool logic so that borrow requests can better respect the timeout.

Technical details

When a connection is requested and none is available, new connections would be created in the application's thread. In case of network issues, this would block the application's thread, possibly for much longer than the borrowConnectionTimeout setting would (and should) allow. That's because there is no easy way to interrupt a blocked IO request.

We now improved this as follows:

  • There is a separate background thread that grows the pool when needed.
  • The application's thread waits for this thread to grow the pool, but no longer than specified by borrowConnectionTimeout.

Changes impacting client API

No real changes are needed, except that it should work better.

Feature189885
Refactor shutdown: improve waiting for in-flight transactions

Description

We have simplified and improved the shutdown logic.

Technical details

Shutdown used to wait for a timeout bound by the value of com.atomikos.icatch.default_max_wait_time_on_shutdown. Recovery itself is already bound by a different parameter: com.atomikos.icatch.default_max_timeout. The previous logic used to mix those two and the results were not always clear.

We have simplified this to the following:

  • Shutdown waits for all active transactions to finish in the JVM.
  • Then it performs a recovery pass to clean up as much as possible.
  • If both previous steps worked fine then there are no pending transactions and the transaction log files can be deleted.
  • On the other hand, if either step has issues then the transaction log files have to be kept (we log a warning for that).

Changes impacting client API

You no longer need com.atomikos.icatch.default_max_wait_time_on_shutdown in your jta.properties file. Beware that shutdown duration is bound by the value of com.atomikos.icatch.default_max_timeout - unless you use the "forceShutdown" option.

Feature182107
Remove user / password properties from MessageDrivenContainer

Description

The user and password properties have been removed from com.atomikos.jms.extra.MessageDrivenContainer because they were never used anyway.

Technical details

Instances of this class delegate to com.atomikos.jms.AtomikosConnectionFactoryBean to create connections. The latter is also configured with a user and password, and those are the values that are actually being used.

As a result, keeping two unused properties in the com.atomikos.jms.extra.MessageDrivenContainer class was confusing - so we have removed those.

Changes impacting client API

You need to remove any references to these properties from your configuration.

Feature199528
Drop reaping functionality from the pools

Description

We've removed the reaping functionality from the pools.

Technical details

Reaping was when our pools would take away connections that were being held onto for too long.

Historically, reaping functionality has caused more problems / confusion than it solved. Moreover, it was intended to fix application-level connection leaks, meaning bugs in the application (as opposed to bugs in our code base). We felt that became a source of needless complexity.

We believe that the correct way of fixing application-level connection leaks is by fixing the application, rather than abruptly reaping connections away from that application. So our 6.0 release seemed a good time to remove that feature.

Changes impacting client API

Remove any references to reapTimeout from your configuration.

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.

Bug200555
Also close Callable- and PreparedStatements when JDBC connection is closed

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

Description

Now you can close a JDBC connection and also have the Callable- and PreparedStatements closed automatically.

Technical details

When a JDBC connection is closed by the application (returned to the pool) then the JDBC specification requires all pending statements to be closed as well.

We supported this, but apparently this was not done for all statement types. We fixed this now.

This issue is marked as severity 4 (development use) because we had no real bug reports from any customers. It was something we noticed during a code review.

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.

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.

Bug200925
Improve handling of null xaresource

Severity:3
Affected version(s):3.9.x, 4.0.x, 5.0.x

Description

We've refined how we deal with lost XA connections during the commit phase.

Technical details

Some connection issues would lead to needless heuristic exceptions during commit, in particular when the commit was 1-phase (where failure to reach the backend results in resource-internal rollback anyway).We have now refined this so there are no needless heuristic exceptions any more in these cases. At the same time, we have also tried to minimise the number of cases where such connection issues remain.

Changes impacting client API

None.

Bug201164
Avoid ConcurrentModificationException during trace logging in the pool

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

Description

You can now use our pools with TRACE logging and get less exceptions.

Technical details

The issue details are described in this GitHub issue.

Changes impacting client API

None.

Issue201646
Spring Boot 2 starter: also add jta and jms versions of Spring Boot's POM to the starter project

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

Description

Unlike Spring Boot 3 support, we did not yet add the JMS and JTA dependencies in the Spring Boot 2 starter.

Technical details

We still have to add the JMS and JTA dependencies in the Spring Boot 2 starter. This is needed because of the removal of transitive dependencies. Until then, you will have to add them yourself.

Free Download

Bug181871
Avoid that ConnectionPoolWithConcurrentValidation grows beyond maxPoolSize

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

Description

We've ported a fix from our commercial release that prevents the pool from exceeding its maxPoolSize.

Technical details

The concurrent pool does not enforce synchronization so when it:

  1. checks if the pool can grow and then
  2. actually grows it

… a different thread may have done the same and the pool grows too much.

Solution: we've made growPool (with existing synchronized block) check maxSize again, and don't grow if already at the maximum.

Changes impacting client API

None.

Review: Going from Architect to Architecting: the Evolution of a Key Role
How evolutionary trends like agile and tooling support are changing the way architects should work

21 Dec 2022 | Guy Pardon | Review, Vision

This is our review of an excellent article published at InfoQ by some of our colleagues at Red Hat. See the references section at the end for the original publication, but this overview aims to give you all of the insights and more in just a few lines of text. Where applicable the content has been complemented with lessons learned from our own experience…

Cybercrime and enterprise software
Supply chain attacks via public repositories

16 Nov 2022 | Guy Pardon | Review, Tech tips, Vision |

The bad guys are trying to get into your projects. What can you do to avoid pulling in bad code?

TransactionsEssentials 5.0.9
Release notes for 5.0.9

21 Feb 2022 | Guy Pardon | TransactionsEssentials

Feature185294
Add gRPC support and examples

We now offer remoting support for gRPC so your transactions can span gRPC calls.

Technical details

Sometimes you may want commit or rollback to extend across one more more outgoing gRPC calls. This is now possible.

See the example module: examples-jta-grpc in the download for a working sample.

Changes impacting client API

New interceptors for your gRPC architecture are included.

Feature188756
Add spring boot starter

Generously donated by Pivotal's Spring Boot team, we were able to add the Spring Boot starter module to our code base.

Technical details

Instead of adding Spring's starter module, you should now add "our" starter module to your Spring Boot project's pom.

In particular, instead of specifying:

   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jta-atomikos</artifactId>
   </dependency>

You should now specify:

   <dependency>
      <groupId>com.atomikos</groupId>
      <artifactId>transactions-spring-boot-starter</artifactId>
      <version>5.0.9</version> <!-- or any later atomikos release that contains our starter module -->
   </dependency>

Additional details are here...

Changes impacting client API

No real API changes, only pom dependency changes.

Feature189603
API extension to allow triggering recovery by the application

You can now explicitly trigger recovery in your application, via our API.

Technical details

Recovery already happens periodically, in the background. For bigger clusters that connect to the same database (or other shared resource) this can cause a high load on the backend, because of many such background threads hitting the backend at the same time. This is especially true if most cluster nodes start up at the same time with the same configuration for recovery, and are NOT using LogCloud Documentation. To alleviate this, you can now have a bit more control over when recovery happens, like this:

import com.atomikos.icatch.RecoveryService;
import com.atomikos.icatch.config.Configuration;

boolean lax = true; //false to force recovery, true to allow intelligent mode
RecoveryService rs = Configuration.getRecoveryService();
rs.performRecovery(lax);

In order for this to work, make sure to set (in jta.properties):

# set to Long.MAX_VALUE so background recovery is disabled
com.atomikos.icatch.recovery_delay=9223372036854775807L 

Changes impacting client API

We have added methods on an existing API interface, which does not break existing clients.

Bug189264
Make sure timed out transactions are cleaned up in the JVM

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

Description

Timed out transactions (in particular heuristic hazard cases after connection issues) used to stay around in the JVM and kept on generating timeout events. This has now been fixed.

Technical details

Abandoned transaction instances now also stop any pending threads that generate timeout warnings. This prevents timed out transactions from generating endless warnings that are no longer relevant.

Changes impacting client API

None.

Bug189263
JtaUnawareThreadLocalConnection: close should notify pool for reuse

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

Description

We optimised connection pool efficiency for non-JTA/XA aware use cases, so connections are reused more efficiently when waiting for busy connections.

Technical details

Previously, waiting connection requests were not notified immediately when a busy connection was being closed (i.e., marked for reuse) by the application. This has now been fixed.

Changes impacting client API

None.

Bug188918
XaResourceTransaction: don't log ERROR when xaresource is null

Severity:2
Affected version(s):5.0

Description

In some rare cases the XAResource used for committing a transaction after prepare may become null (presumably due to connection errors, unconfirmed though). Instead of logging an error (like we used to), we now trust background-level recovery to handle this - for which it was designed in the first place. This should avoid repeated the errors logged in such a case.

Technical details

This "bug" would lead to millisecond-level repeated errors similar to the following:

19/11/2020 15:20:43.467 [Atomikos:3321] ERROR com.atomikos.icatch.imp.CommitMessage - Unexpected error in commit
com.atomikos.icatch.HeurHazardException: XAResourceTransaction: 31302E3235342E3134362E3131302E746D313539353531353037383735393139373038:31302E3235342E3134362E3131302E746D373030333533: no XAResource to commit?
        at com.atomikos.datasource.xa.XAResourceTransaction.commit(XAResourceTransaction.java:529)
        at com.atomikos.icatch.imp.CommitMessage.send(CommitMessage.java:52)
        at com.atomikos.icatch.imp.CommitMessage.send(CommitMessage.java:23)
        at com.atomikos.icatch.imp.PropagationMessage.submit(PropagationMessage.java:67)
        at com.atomikos.icatch.imp.Propagator$PropagatorThread.run(Propagator.java:63)
        at com.atomikos.icatch.imp.Propagator.submitPropagationMessage(Propagator.java:42)
        at com.atomikos.icatch.imp.HeurHazardStateHandler.onTimeout(HeurHazardStateHandler.java:71)
        at com.atomikos.icatch.imp.CoordinatorImp.alarm(CoordinatorImp.java:650)
        at com.atomikos.timing.PooledAlarmTimer.notifyListeners(PooledAlarmTimer.java:95)
        at com.atomikos.timing.PooledAlarmTimer.run(PooledAlarmTimer.java:82)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
19/11/2020 15:20:53.468 [Atomikos:3321] ERROR com.atomikos.datasource.xa.XAResourceTransaction - XAResourceTransaction: 31302E3235342E3134362E3131302E746D313539353531353037383735393139373038:31302E3235342E3134362E3131302E746D373030333533: no XAResource to commit?

Now we no longer log these as errors, since we designed recovery to take care of exactly those kinds of exceptions.

Changes impacting client API

None.

Bug185591
Bug in JDBC statement proxy: callable statement

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

Description

Fixed a bug that would happen in certain class loading environments and prevented CallableStatements from being created.

Technical details

Fixed a bug that would happen in certain class loading environments and prevented CallableStatements from being created. This would lead to errors like this:

java.lang.ClassCastException: com.sun.proxy.$Proxy364 cannot be cast to java.sql.CallableStatement
            at com.atomikos.jdbc.internal.AbstractJdbcConnectionProxy.prepareCall(AbstractJdbcConnectionProxy.java:73)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            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.$Proxy64.prepareCall(Unknown Source)

Changes impacting client API

None.

Bug183884
Remoting participants do not respect commit ordering

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

Description

Remoting participants now also respect commit ordering so you can avoid issues with JMS notifications going out before the backend databases are up to date.

Technical details

Consider the following scenario for your microservice:

1. receive a JMS message 2. do a remote call to a different microservice that in turn updates a DB 3. send out a JMS "ticket" message

Previously, the JMS message (3) would be committed first, when DB of the remote call in 2 still needed to commit. Recipients of (3) would sometimes not see the updates in the DB when they receive the message.

This has now been fixed, by incorporating the remote participant of step 2 in the commit order.

Changes impacting client API

None.

Bug182578
NPE when checking class loaders

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

Description

We now check for null when adding class loaders to create dynamic proxies.

Technical details

At least one user has reported null issues when creating a dynamic proxy, like this:

java.lang.NullPointerException: null
       at java.util.ArrayDeque.addLast(ArrayDeque.java:249) ~[?:1.8.0_251]
       at java.util.ArrayDeque.add(ArrayDeque.java:423) ~[?:1.8.0_251]
       at com.atomikos.util.DynamicProxySupport.getClassLoadersToTry(DynamicProxySupport.java:194) ~[?:?]
       at com.atomikos.util.DynamicProxySupport.createDynamicProxy(DynamicProxySupport.java:189) ~[?:?]
       at com.atomikos.jdbc.internal.AtomikosXAPooledConnection.doCreateConnectionProxy(AtomikosXAPooledConnection.java:119) ~[?:?]
       at com.atomikos.jdbc.internal.AtomikosXAPooledConnection.doCreateConnectionProxy(AtomikosXAPooledConnection.java:31) ~[?:?
       at com.atomikos.datasource.pool.AbstractXPooledConnection.createConnectionProxy(AbstractXPooledConnection.java:86) ~[?:?]
       at com.atomikos.datasource.pool.ConnectionPoolWithConcurrentValidation.concurrentlyTryToUse(ConnectionPoolWithConcurrentValidation.java:61) ~[?:?]
       at com.atomikos.datasource.pool.ConnectionPoolWithConcurrentValidation.retrieveFirstAvailableConnection(ConnectionPoolWithConcurrentValidation.java:43) ~[?:?]
       at com.atomikos.datasource.pool.ConnectionPool.retrieveFirstAvailableConnectionAndGrowPoolIfNecessary(ConnectionPool.java:140) ~[?:?]
       at com.atomikos.datasource.pool.ConnectionPool.findOrWaitForAnAvailableConnection(ConnectionPool.java:128) ~[?:?]
       at com.atomikos.datasource.pool.ConnectionPool.borrowConnection(ConnectionPool.java:119) ~[?:?]
       at com.atomikos.jdbc.internal.AbstractDataSourceBean.getConnection(AbstractDataSourceBean.java:371) ~[?:?]

We now fixed this by simply checking if a class loader is not null before attempting to use it.

Changes impacting client API

None.

Bug185558
Avoid passing all remote participants as direct participants for remoting transactions

Severity

2

Affected versions

5.0.x

Description

We used to pass all remote participants as direct participants, meaning that two-phase commit would sometimes be repeated and fail. This would particularly be the case in "diamond" calls - or also in deeper call hierarchies of more than one level down.

Technical details

Consider a remoting client service A calling another remoting service B.

For remoting we distinguish between direct participants (i.e., endpoints at B to be included for two-phase commit at A) and indirect participants (i.e., URIs added as metadata only for checking orphaned calls).

The class DefaultImportingTransactionManager in module transactions-remoting used to pass all its remote participants as direct participants, i.e. participants to be included in the remoting's two-phase commit set. In particular for diamond-shaped calls (A calls B and C, and both B and C in turn call D) this would give repeated two-phase commit calls to D, because A would incorrectly receive D as a direct participant via the call hierarchies of both B and C.

We fixed this, and for this specific case A would now only receive 2 direct participants: B and C.

This fix also resolves an issue with a simpler call stack: A → B → C, where C would also be called for two-phase commit by both A and B. The is no longer the case.

Changes impacting client API

None.

Special thanks

Thanks to @beanww for reporting this on GitHub.

Bug185557
Avoid app-server thread leak when deployed in servers like Tomcat

Severity

3

Affected versions

4.0.x, 5.0.x

Description

Server-side (Tomcat) integration created threads for individual transactions (at web app level) with the class loader of the web application. This would cause (Tomcat) warnings when the web application is stopped because those threads will hang around in the thread pool.

Solution: we now start new threads with the server-level class loader.

Technical details

If you have the transaction core at the server level (in the server's classpath) then individual transactions started in the web application will use the server-level thread pool of Atomikos (named com.atomikos.thread.TaskManager).

This would typically give warnings (in Tomcat) like this when the web application is being shut down:

WARNING [http-nio-3030-exec-6] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [mywebapp] appears to have started a thread named [Atomikos:2] but has failed to stop it. This is very likely to create a memory leak.

That's because the server-side thread pool threads used to be created with the web application's class loader.

This also happened for our built-in Tomcat integration (since it is configured at the server-level).

We now create those threads with the thread pool's classloader instead. When configured at the server level, this will no longer be the application's class loader and that seems to prevent this problem.

Changes impacting client API

None.

Special thanks

Special thanks to @jjimjam for reporting this on GitHub, and thanks also to the Jetty - Webtide team for extra input.

Bug189921
Avoid that exceptions when writing a checkpoint needlessly corrupt the transaction log

Severity

2

Affected versions

4.0.x, 5.0.x

Description

You now no longer get "Log corrupted - restart JVM" exceptions after you interrupt a thread that is writing to the transaction log file, or after any other exception that make a log checkpoint fail.

Technical details

Any exceptions during a checkpoint (such as when a thread was interrupted during transaction log file I/O) would lead to a generic exception handling block in our com.atomikos.recovery.fs.CachedRepository class, leaving the instance in an invalid state:

2021-03-01 16:15:56.662 ERROR 41669 --- [pool-1-thread-1] c.a.recovery.fs.FileSystemRepository     : Failed to write checkpoint

java.nio.channels.ClosedByInterruptException: null
   at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202) ~[na:1.8.0_192]
   at sun.nio.ch.FileChannelImpl.force(FileChannelImpl.java:392) ~[na:1.8.0_192]
   at com.atomikos.recovery.fs.FileSystemRepository.writeCheckpoint(FileSystemRepository.java:196) ~[transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.recovery.fs.CachedRepository.performCheckpoint(CachedRepository.java:84) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.recovery.fs.CachedRepository.put(CachedRepository.java:77) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.recovery.fs.OltpLogImp.write(OltpLogImp.java:46) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.persistence.imp.StateRecoveryManagerImp.preEnter(StateRecoveryManagerImp.java:51) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.finitestates.FSMImp.notifyListeners(FSMImp.java:164) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.finitestates.FSMImp.setState(FSMImp.java:251) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.CoordinatorImp.setState(CoordinatorImp.java:284) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.CoordinatorStateHandler.commitFromWithinCallback(CoordinatorStateHandler.java:346) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.ActiveStateHandler$6.doCommit(ActiveStateHandler.java:273) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.CoordinatorStateHandler.commitWithAfterCompletionNotification(CoordinatorStateHandler.java:587) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.ActiveStateHandler.commit(ActiveStateHandler.java:268) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.CoordinatorImp.commit(CoordinatorImp.java:550) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.CoordinatorImp.terminate(CoordinatorImp.java:682) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.CompositeTransactionImp.commit(CompositeTransactionImp.java:279) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.jta.TransactionImp.commit(TransactionImp.java:168) [transactions-jta-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.jta.TransactionManagerImp.commit(TransactionManagerImp.java:428) [transactions-jta-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.jta.UserTransactionManager.commit(UserTransactionManager.java:160) [transactions-jta-5.0.9-SNAPSHOT.jar:na]
   at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1035) [spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) [spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) [spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:152) [spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
   at com.example.atomikos.AtomikosApplicationTests.lambda$4(AtomikosApplicationTests.java:78) [test-classes/:na]
   at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_192]
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_192]
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_192]
   at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_192]

Later requests trying to read from the transaction logs would get systematic corruption errors like this:

com.atomikos.recovery.LogReadException: Log corrupted - restart JVM
   at com.atomikos.recovery.fs.CachedRepository.assertNotCorrupted(CachedRepository.java:137) ~[transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.recovery.fs.CachedRepository.findAllCommittingCoordinatorLogEntries(CachedRepository.java:145) ~[transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.recovery.fs.RecoveryLogImp.getExpiredPendingCommittingTransactionRecordsAt(RecoveryLogImp.java:52) ~[transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.RecoveryDomainService.performRecovery(RecoveryDomainService.java:76) ~[transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.icatch.imp.RecoveryDomainService$1.alarm(RecoveryDomainService.java:55) [transactions-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.timing.PooledAlarmTimer.notifyListeners(PooledAlarmTimer.java:101) [atomikos-util-5.0.9-SNAPSHOT.jar:na]
   at com.atomikos.timing.PooledAlarmTimer.run(PooledAlarmTimer.java:88) [atomikos-util-5.0.9-SNAPSHOT.jar:na]
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_192]
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_192]
   at java.lang.Thread.run(Thread.java:748) [na:1.8.0_192]

This has now been fixed.

Changes impacting client API

None.

About Severity

The severity levels we use are defined in our support terms and conditions.

Corporate Information

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

Contact Us

Copyright 2024 Atomikos BVBA | Our Privacy Policy
This page was cached on 19 Mar 2024 - 10:41.
By using this site you agree to our cookies. More info. That's Fine