CAMEL-23234: JTA Shutdown rollback#22204
Conversation
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
gnodet
left a comment
There was a problem hiding this comment.
Claude Code on behalf of Guillaume Nodet
Nice fix — the dual mechanism (in-flight set + post-processing preparingShutdown check) covers the race window well, and preparingShutdown is properly volatile in both implementations. Tests are thorough, especially the integration test with its well-documented 10-step sequence.
Two minor items:
-
parent/pom.xmlproperty ordering:agroal-versionis inserted betweenactivemq6-versionandactivemq-artemis-version, breaking alphabetical order. It should be placed afteractivemq-artemis-version(sinceag>ac). -
TransactionalClientDataSourceForcedShutdownTest.java:676:Thread.sleep(2000)to "give the exchange time to complete" is a flaky pattern. ACountDownLatchorAwaitilitywould be more reliable.
gnodet
left a comment
There was a problem hiding this comment.
Claude Code on behalf of Guillaume Nodet
The fix itself looks solid — the dual mechanism (in-flight set + post-processing preparingShutdown check) is well designed and thread-safe.
However, I'd like to see two things addressed before merging:
-
parent/pom.xmlproperty ordering:agroal-versionis inserted betweenactivemq6-versionandactivemq-artemis-version, breaking alphabetical order. It should be placed afteractivemq-artemis-version. -
TransactionalClientDataSourceForcedShutdownTest.java:676—Thread.sleep(2000)must go. We've spent significant effort hunting down and eliminatingThread.sleep()in tests because they are a recurring source of flaky CI builds. They either sleep too long (slow builds) or not long enough (random failures on loaded CI agents). Please replace with a proper synchronization mechanism — add aCountDownLatchthat the exchange signals when processing completes, thenawait()it with a timeout. The other tests in this PR already use this pattern correctly, so it should be straightforward.
…await - Move agroal-version after activemq-artemis-version for alphabetical order - Replace Thread.sleep(2000) with executor.awaitTermination() in TransactionalClientDataSourceForcedShutdownTest to avoid flaky tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gnodet
left a comment
There was a problem hiding this comment.
Claude Code on behalf of Guillaume Nodet
LGTM, thanks for the fix!
JIRA: CAMEL-23234
Description
Problem: When a Camel application receives a graceful shutdown while a transacted route is mid-processing (e.g., during a long-running stored procedure or delay that exceeds the grace period), in-flight transactions are committed instead of rolled back. The container destroys the connection pool during shutdown, but the transaction has already committed partial work.
Fix: The TransactionErrorHandler (both camel-jta and camel-spring) now tracks in-flight transacted exchanges. When DefaultShutdownStrategy triggers a forced shutdown after the grace period expires, prepareShutdown(forced=true) marks all in-flight exchanges as rollbackOnly. Additionally, after processByErrorHandler() returns, a preparingShutdown check sets rollbackOnly on any exchange that completed processing after the shutdown flag was set. Both mechanisms cause the transaction policy to throw, triggering a rollback before the connection pool is destroyed.