[ 
https://issues.apache.org/jira/browse/CAMEL-26743?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Work on CAMEL-26743 started by shashank.
----------------------------------------
> camel-sql - JdbcOrphanLockAwareIdempotentRepository: the keep-alive deadlocks 
> with add and remove on a small connection pool, and leases expire
> -----------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-26743
>                 URL: https://issues.apache.org/jira/browse/CAMEL-26743
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-sql
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> {{JdbcOrphanLockAwareIdempotentRepository}} guards its set of held keys with 
> a {{StampedLock}}, and holds the lock while SQL runs:
> * {{keepAlive()}} takes the read lock and then starts its transaction, which 
> borrows a connection from the pool.
> * {{add()}} and {{remove()}} borrow a connection first (the transaction of 
> {{AbstractJdbcMessageIdRepository}}), and then take the write lock in 
> {{insert}} / {{delete}}, around the COUNT, INSERT, UPDATE or DELETE.
> With more threads using the repository than the pool has connections, the two 
> orders form a cycle: the keep-alive holds the read lock and waits for a 
> connection, while every connection is held by an add or remove that waits for 
> the write lock. With a pool that waits as long as it takes (the defaults of 
> plain Agroal and DBCP2) the node deadlocks: no add or remove completes again. 
> With a pool timeout (HikariCP: 30 s) the keep-alive round fails after the 
> timeout, only logged at ERROR, and the add/remove calls stall until then; 
> under steady load the next round can be caught the same way. With an infinite 
> wait no lease is refreshed again; with a timeout, when rounds keep failing 
> for {{lockMaxAgeMillis}}, the leases expire. Then another node takes over 
> keys this node is still processing, so a message is processed twice at the 
> same time.
> The same lock also makes the keep-alive wait for any slow statement of an add 
> or remove: an INSERT that waits for a row lock of another node (for example a 
> transacted route on that node holding an uncommitted insert of the same key) 
> blocks the keep-alive of the whole node for as long as it waits. PostgreSQL, 
> Oracle and SQL Server have no lock timeout by default.
> The lock only protects the in-memory set; it does not make the COUNT and the 
> INSERT atomic, as the transaction of add or remove commits after the lock is 
> released.
> Expected: the keep-alive and add/remove never wait for each other while one 
> of them holds a connection, and the keep-alive refreshes the held keys while 
> an add or remove runs.
> Suggested fix: keep the held keys in a concurrent set and hold no lock across 
> SQL; the keep-alive takes its timestamp and the keys once it has its 
> connection.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to