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

Federico Mariani updated CAMEL-24048:
-------------------------------------
    Attachment: JdbcMessageIdRepositoryDuplicateInsertRaceTest.java

> camel-sql - stale remove() silently completes in JdbcAggregationRepository; 
> idempotent add() leaks DuplicateKeyException; TokenMgrError escapes stored 
> template parser
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24048
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24048
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-sql
>            Reporter: Federico Mariani
>            Priority: Major
>         Attachments: JdbcAggregationRepositoryStaleRemoveTest.java, 
> JdbcMessageIdRepositoryDuplicateInsertRaceTest.java, 
> TemplateParserLexicalErrorTest.java
>
>
> Three correctness defects found during a camel-sql review, each with a 
> deterministic reproducer test attached (all fail on current main, must pass 
> after the fix):
> *1. JdbcAggregationRepository.remove() ignores the optimistic delete count*
> {{remove()}} deletes with {{WHERE id = ? AND version = ?}} but discards the 
> update count. With a stale version (a concurrent add on another node bumped 
> it), 0 rows are deleted, yet the stale aggregated exchange is still inserted 
> into the completed table and {{remove()}} reports success: the live 
> aggregation survives and completes again later (duplicate downstream 
> delivery) while a bogus completed entry also exists. A 0-count delete should 
> raise {{OptimisticLockingException}}, symmetric with {{updateHelper()}}. Same 
> pattern in {{ClusteredJdbcAggregationRepository.remove()}}.
> Reproducer: JdbcAggregationRepositoryStaleRemoveTest.java
> *2. AbstractJdbcMessageIdRepository.add() propagates DuplicateKeyException on 
> a cross-node insert race*
> {{add()}} is check-then-act (count, then insert). When a competing node 
> inserts the same key between the two statements, the primary-key violation 
> escapes {{add()}} as a raw Spring {{DuplicateKeyException}} and fails the 
> exchange, instead of being treated as "already processed" (return false, like 
> the plain count!=0 case). Idempotency itself holds, but the losing exchange 
> goes to redelivery/DLQ. Care is needed not to mask rollback-only state when 
> {{add()}} joins a caller's transaction ({{PROPAGATION_REQUIRED}} is a 
> documented feature).
> Reproducer: JdbcMessageIdRepositoryDuplicateInsertRaceTest.java (simulates 
> the race deterministically with a DataSource wrapper)
> *3. sql-stored: lexical errors escape as java.lang.Error*
> {{TemplateParser.parseTemplate()}} only catches {{ParseException}}, but the 
> generated JavaCC lexer throws {{TokenMgrError}} - an {{Error}} - for any 
> character outside the token alphabet (e.g. {{;}}). With 
> {{useMessageBodyForTemplate=true}} or the {{CamelSqlStoredTemplate}} header 
> the template comes from message content, so a stray character raises a raw 
> {{Error}} in the route that {{onException}} handlers never see. Lexical 
> errors should be wrapped in {{ParseRuntimeException}} like parse errors are.
> Reproducer: TemplateParserLexicalErrorTest.java



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to