fix(central): optimize upsertForm version query and handle concurrent insert collision - #181
fix(central): optimize upsertForm version query and handle concurrent insert collision#181Lekerr wants to merge 3 commits into
Conversation
…retry on concurrent insert collision
|
augment review |
🤖 Augment PR SummarySummary: This PR optimizes PostgreSQL form upserts and adds retry handling for concurrent version creation. Changes:
🤖 Was this summary useful? React with 👍 or 👎 |
| case cause: PSQLException => cause.getSQLState == "23505" | ||
| case _ => false | ||
| case _ => false | ||
| } && Schedule.recurs(3) |
There was a problem hiding this comment.
With five callers that all read the same version, one insert succeeds per round while the remaining calls collide; after the initial attempt plus these three recurrences, one of five callers can still receive the 23505 failure. This means the new five-call concurrency contract is not guaranteed, and the unsynchronized test may pass without reaching that worst-case interleaving.
Severity: medium
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
| case cause: PSQLException => cause.getSQLState == "23505" | ||
| case _ => false | ||
| case _ => false | ||
| } && Schedule.recurs(3) |
There was a problem hiding this comment.
Schedule.recurs(3) permits only three retries after the initial attempt. If five calls concurrently read the same maximum version, only one can commit in each round, so the fifth call still collides on its third retry and fails with 23505; this does not provide the stated collision handling for the new five-call scenario (and can occur with a pool larger than the test pool).
Severity: medium
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
…ng herd on concurrent upsert
|
augment review |
Closes #99
Problem
upsertFormhad two issues:MAXin Scala — unnecessary data transferMAX(version), compute the samenextVersion, and both attempt an INSERT — causing an unhandled PRIMARY KEY violationSolution
SELECT COALESCE(MAX(version), 0) + 1, COUNT(*) = 0 FROM forms WHERE id = $idREPEATABLE_READtoREAD_COMMITTEDand added.retry()onSqlExceptionwrapping a23505(unique_violation) — the entire transaction retries with fresh dataTest
Added concurrent test: 5 parallel
upsertFormcalls on the sameid— verifies all 5 versions are created without collision