Skip to content

v0.4.1 — fix slide-switch deadlock storm

Choose a tag to compare

@asm0dey asm0dey released this 18 May 07:55
· 89 commits to main since this release

Highlights

Slide-switch deadlock storm fixed. When a Slidev deck mounted multiple <PollResults /> panels (e.g. main view + presenter view), every slide switch fired close + activate POSTs from each mounted panel. Concurrent activates on the same poll's poll_questions rows acquired per-tuple row locks in different orders and deadlocked (PostgreSQL 40P01). Hikari connections then piled up on deadlock-victim retries and the next backoffice PATCH appeared to hang.

Fix

  • PollRepositoryImpl.activateQuestion and closeActiveQuestion now wrap the state-flipping UPDATE in a dsl.transactionResult and take SELECT polls … FOR UPDATE on the owning poll row up front. Every activate / close / header-update on the same poll serialises behind one row lock; the admin PATCH naturally takes the same lock via its UPDATE polls, so the two paths can no longer interleave their per-question locks.
  • Added a package-private findById(DSLContext, UUID) overload so the post-mutation read inside the transaction callback sees the writes the transaction has just made (the outer auto-commit dsl would have read pre-commit state on a different connection).

Tests

  • New PollActivateDeadlockIT: 16 threads × 25 iterations of interleaved activate(qN) / closeActiveQuestion / updateHeader on a single poll. Parametrised over PostgreSQL and H2. Asserts no SQL exception and the at-most-one-ACTIVE-question invariant.

Full changelog

v0.4.0...v0.4.1