allthingssecurity opened a new pull request, #27637: URL: https://github.com/apache/camel/pull/27637
# Description [CAMEL-25504](https://issues.apache.org/jira/browse/CAMEL-25504) `DefaultShutdownStrategy` calls `prepareShutdown(suspendOnly=false, forced=false)` on the route services before it waits for the in-flight exchanges, and `prepareShutdown(false, forced=true)` only after the shutdown timeout expired. The camel-jta `TransactionErrorHandler` and the camel-spring `org.apache.camel.spring.spi.TransactionErrorHandler` (through `RedeliveryErrorHandler.prepareShutdown`) set `preparingShutdown` on both calls, and since CAMEL-23234 both mark every exchange that finishes while `preparingShutdown` is set as rollback only. So a transacted exchange that completes normally inside the grace period of a graceful shutdown (context stop, route stop) is rolled back instead of committed. The forcing `TransactionRolledbackException` is swallowed, so a caller that does not redeliver (direct, REST, ProducerTemplate) sees success while the work is rolled back. This change adds, in both handlers, a `forcedShutdown` flag that `prepareShutdown` sets only when `forced` is true (reset with `preparingShutdown` on start and resume), and the check after the route work reads it. The CAMEL-23234 behaviour on timeout is unchanged. With `shutdownNowOnTimeout=false` there is no forced `prepareShutdown`, so an exchange that completes after the timeout is now committed again (as before 4.19). The 4.23 upgrade guide gets a short note. Tests: - New `TransactionalClientDataSourceGracefulShutdownTest` in camel-spring-xml (Spring `DataSourceTransactionManager`, embedded H2, next to `TransactionalClientDataSourceForcedShutdownTest`): a `transacted()` route inserts a book and is held while `context.stop()` runs; a service inside the transacted block releases it from its graceful `prepareShutdown` call. A second test calls `prepareShutdown(false, false)` on the handler directly, as the forced-shutdown test does with `forced=true`. Without the change both fail (`... must not be marked rollback only ==> expected: <false> but was: <true>`, the insert is rolled back). - New `TransactionErrorHandlerGracefulShutdownTest` in camel-jta: an exchange held in a transacted route while `camelContext.stop()` runs, released once the handler received the graceful `prepareShutdown`; and the same directly on the handler with `prepareShutdown(false, false)`. - Without the change: `an exchange that completed during a graceful shutdown must not be marked rollback only ==> expected: <false> but was: <true>` (both tests fail). - With the change: camel-jta 3 classes, 5 tests, 0 failures (the Postgres IT, which covers the forced path only, was skipped without Docker); camel-spring-xml 1184 tests, 0 failures, 26 skipped (camel-spring itself has no tests). `TransactionalClientDataSourceForcedShutdownTest` and the suspend/resume tests still pass. Found with a TLA+ model of the handler and the shutdown strategy: "an exchange that completed successfully before the shutdown timeout is committed" is violated in 7 steps (begin, consumer stopped, work done, graceful prepare, the check marks rollback only, rollback). I then reproduced it with the real components. # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for the change (usually before you start working on it). # Apache Camel coding standards and style - [x] I checked that each commit in the pull request has a meaningful subject line and body. - [ ] I have run `mvn clean install -DskipTests` locally from root folder and I have committed all auto-generated changes. (I built and tested camel-jta, camel-spring and camel-spring-xml, including the formatter and import-sort plugins. I did not run the full root build.) # AI-assisted contributions - [x] If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR description identifies the AI tool used. This PR was prepared with Claude Code (Claude Opus 5.5). The commit carries a `Co-Authored-By` trailer. _Claude Code on behalf of allthingssecurity_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
