ReviewOS

stacks/bun-query-builder

fix(transactions): afterCommit errors retry already-committed writes

#1144
Closed glennmichael123 opened this 8 days ago ·
8 days ago

Reproduction

On main 5f271d5 with Bun 1.4.1, an afterCommit callback that throws an error matching the retry classifier causes a successfully committed transaction to execute again.

Reproduced on disposable native SQLite, the SQLite wrapper, MySQL 8.4.5 and Postgres 16. A transaction inserts one synthetic row, with retries: 1. Its afterCommit callback throws new Error('database is locked: downstream callback'). Result: two committed rows, two callback executions and a rollback notification, even though both attempts committed.

Cause

opts.afterCommit() runs inside the same try/catch as runWith(). That catch handles database rollback/retry, but the driver has already committed when the callback runs. The error classifier therefore applies to the wrong phase. Async callbacks are also not awaited, despite the documented async example in docs/guide/transactions.md.

Fix and acceptance

  • Move callback execution outside the transaction retry/rollback catch.
  • Await synchronous or asynchronous afterCommit callbacks and propagate their original error without replaying writes or invoking rollback handlers.
  • Keep genuine failed transaction attempts retryable and preserve the callback's successful return value.
  • Required cross-driver regression tests; no schema or migration changes.

This is separate from query-cache isolation (#1143). The failure is in transaction completion handling, independent of caching.

8 days ago

Fixed in 17ac15f. CI passed: https://github.com/stacksjs/bun-query-builder/actions/runs/34692187993 . Local full-suite rerun: 2189 pass, four existing skips. Typecheck, build and changed-file lint passed. Native and wrapper SQLite, MySQL and Postgres regressions cover sync/async callback errors and genuine transaction retries. Verified through the Stacks query-builder wrapper with the candidate dependency. No npm release performed.

Sign in to comment on this issue.