Abhitocode opened a new pull request, #2352:
URL: https://github.com/apache/incubator-kie-kogito-apps/pull/2352

   When a few replicas of the same app start together, they all see an empty 
state and insert the same `(id, version)` rows into `definitions`. All but the 
first hit a primary key violation and the replica dies on startup.
   
   The reason it can't be caught today: `em.merge()` only queues the INSERT, 
and `put` joins the transaction that indexing already runs in, so the INSERT is 
only sent when that outer transaction commits - after any `try`/`catch` around 
`put` has returned.
   
   ### What changed
   
   - **`ProcessDefinitionEntityStorage`** - new `put` overload with the actual 
fix: flush the insert right away so the failure happens where we can catch it, 
run it in a separate transaction so the rollback doesn't kill the caller's 
work, and on a duplicate just return the definition that's already stored.
   
   - **`QuarkusProcessDefinitionEntityStorage`** (jpa-quarkus *and* postgresql) 
- overrides `put` to run the insert in a `@Transactional(REQUIRES_NEW)` method. 
Two copies of the same class, both used by an embedded add-on, so both need it.
   
   - **`SpringBootProcessDefinitionEntityStorage`** (new, springboot) - same 
thing with a`TransactionTemplate`. `@Transactional` doesn't work here: Spring 
ignores it when a class calls its own method, so the insert would just run in 
the caller's transaction.
   
   This is also why the catch sits *outside* the transaction, not inside, here 
a failed flush marks the transaction as rollback only, so the commit still 
fails after the `catch` has run. The exception is different too, Quarkus throws 
`ConstraintViolationException`, Spring Boot throws 
`DataIntegrityViolationException`.
   
   - **`DataIndexStorageProducer`** (springboot) - removed the 
`processDefinitionEntityStorage` bean, otherwise there'd be two beans of the 
same type now that the class above provides it.
   
   ### Tests
   
   `AbstractConcurrentProcessDefinitionStorageIT` plus a PostgreSQL subclass 
per runtime. A plain JDBC connection acts as the competing replica, it inserts 
the row and holds it uncommitted, so the storage still sees nothing and queues 
its own insert, which blocks on the primary key index. The commit is triggered 
from `pg_locks` once that insert is actually waiting, so there are no sleeps.
   
   Closes: https://github.com/apache/incubator-kie-issues/issues/2382
   


-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to