allthingssecurity opened a new pull request, #29533:
URL: https://github.com/apache/camel/pull/29533

   # Description
   
   [CAMEL-26770](https://issues.apache.org/jira/browse/CAMEL-26770)
   
   Found by Claus Ibsen while reviewing #29437 (CAMEL-26743), where 
`JdbcOrphanLockAwareIdempotentRepository` had the same pattern for its 
keep-alive set.
   
   `JdbcCachedMessageIdRepository.add` put the key in its in-memory cache as 
soon as `super.add` returned, before the transaction that inserted the row 
committed. When the add joins a caller's transaction (a transacted route on the 
same `DataSourceTransactionManager`) and that transaction rolls back, the row 
is gone but the key stayed in the cache. `add()` and `contains()` answer from 
the cache first, so the redelivery of the same message was rejected as a 
duplicate, although the database has no row for it. CAMEL-24046 made `add()` 
cache the key only after the insert succeeded; this is the case where the 
insert succeeds and the caller's transaction then rolls back.
   
   Change:
   - In a transaction with synchronization, `add` caches the key in 
`afterCommit` of a `TransactionSynchronization`, so a rolled-back add is never 
cached. Without a transaction it is cached at once, as before.
   - A `remove` of the key, or `clear()`, later in the same transaction cancels 
the pending caching, so a key added and removed in one transaction is not 
cached either.
   - `remove` and `clear()` empty the cache before their delete, as before, and 
now also after it. On a database that locks rows, a `remove` on another thread 
can wait for the row lock of an uncommitted add; when that add commits it 
caches the key, and the delete then removes the row, so the key must be evicted 
again. (H2 does not block there, so this has no test.)
   - Without a caller's transaction, `super.add` runs and commits its own 
transaction, and `add` then caches the key at once, as before. With a caller's 
transaction on another transaction manager (JMS, for example), the repository's 
own transaction commits the row first, and the key is cached when the caller's 
transaction commits; if that one rolls back, the row stays and the key is not 
cached, which only costs a cache miss.
   - As in #29437, two cases still cache a rolled-back key, as before this PR: 
an add inside a savepoint (`PROPAGATION_NESTED`) that rolls back while the 
outer transaction commits, and a JTA transaction that Spring did not start 
(`afterCommit` runs when Spring's scope ends, before the JTA commit).
   
   Tests (H2, no Docker), `JdbcCachedMessageIdRepositoryTransactionTest`, with 
the repository's own `TransactionTemplate` as the caller's transaction:
   - an add in a transaction that rolls back is not a duplicate afterwards 
(`contains` is false, and the redelivery is added);
   - an add in a transaction that commits is not cached before the commit 
(`contains` counts a miss and reads the row) and is answered from the cache 
afterwards (the hit count goes up);
   - an add followed by a `remove`, or by `clear()`, in the same transaction is 
not cached;
   - a plain add is cached as before.
   
   Without the change, the rollback test fails (the key is a duplicate from the 
cache); the add-then-remove and add-then-clear tests guard the cancelling. With 
it 5/5 (20 of 20 runs), and all 31 JDBC idempotent repository tests of 
camel-sql pass (offline).
   
   # 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): 
[CAMEL-26770](https://issues.apache.org/jira/browse/CAMEL-26770).
   
   # 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 camel-sql with the formatter and import-sort plugins and ran its 
idempotent repository tests. No generated file changes. 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]

Reply via email to