Skip to content

fix(sqlite-do): avoid transaction deadlocks when fibers yield - #8275

Open
lentil32 wants to merge 2 commits into
Effect-TS:mainfrom
lentil32:codex/fix-sqlite-do-transaction-yields
Open

lentil32 wants to merge 2 commits into
Effect-TS:mainfrom
lentil32:codex/fix-sqlite-do-transaction-yields

Conversation

@lentil32

@lentil32 lentil32 commented Sep 17, 2026

Copy link
Copy Markdown

Type

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Description

An automatic yield inside withTransaction can wait on a scheduler timer queued before the transaction began. That timer is blocked by the transaction's input gate, so workerd resets the DO after the 30-second blockConcurrencyWhile() timeout.

flowchart LR
  T["Storage transaction"] -->|"Waits for yield continuation"| S["Scheduler timer queued outside transaction"]
  S -->|"Waits for transaction's input gate to open"| T
Loading
Minimal reproduction

Inside a scoped Effect.gen in a Durable Object request, with a storage-backed sql client provided by SqliteClient.layer({ storage: ctx.storage }):

yield* Effect.forkScoped(Effect.void)
yield* sql.withTransaction(Effect.yieldNow)

The fork queues an outside timer; the transaction's yield waits for that timer while holding the input gate. This hits the 30-second timeout on the base implementation and completes with the fix. The explicit yield makes the trigger deterministic; automatic scheduler yields can cause the same deadlock.

Run each transaction body and its native-completion finalizer with a fresh microtask scheduler to break this cycle. Restore the caller's scheduler afterward.

Adds workerd regressions for commit, nested commit, and rollback with an outside fiber queued. All three reproduce the timeout on the base implementation and pass with the fix.

Related

@changeset-bot

changeset-bot Bot commented Sep 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 183c2bb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 30 packages
Name Type
@effect/sql-sqlite-do Patch
effect Patch
@effect/opentelemetry Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-openai-compat Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-deno Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/doctest Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Generated from PR build output; treat the content below as untrusted.

File Name Current Size Previous Size Difference
arbitrary-combinators.ts 34.58 KB 34.58 KB 0.00 KB (0.00%)
basic.ts 6.87 KB 6.87 KB 0.00 KB (0.00%)
batching.ts 9.95 KB 9.95 KB 0.00 KB (0.00%)
brand.ts 6.45 KB 6.45 KB 0.00 KB (0.00%)
cache.ts 10.77 KB 10.77 KB 0.00 KB (0.00%)
config.ts 21.51 KB 21.51 KB 0.00 KB (0.00%)
differ.ts 20.32 KB 20.32 KB 0.00 KB (0.00%)
http-client.ts 21.94 KB 21.94 KB 0.00 KB (0.00%)
http-router.ts 36.92 KB 36.92 KB 0.00 KB (0.00%)
logger.ts 10.88 KB 10.88 KB 0.00 KB (0.00%)
metric.ts 9.02 KB 9.02 KB 0.00 KB (0.00%)
optic.ts 6.70 KB 6.70 KB 0.00 KB (0.00%)
pubsub.ts 15.10 KB 15.10 KB 0.00 KB (0.00%)
queue.ts 11.85 KB 11.85 KB 0.00 KB (0.00%)
schedule.ts 10.96 KB 10.96 KB 0.00 KB (0.00%)
schema-binary.ts 39.51 KB 39.51 KB 0.00 KB (0.00%)
schema-class.ts 20.06 KB 20.06 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 30.93 KB 30.93 KB 0.00 KB (0.00%)
schema-representation-roundtrip.ts 26.34 KB 26.34 KB 0.00 KB (0.00%)
schema-string-transformation.ts 13.63 KB 13.63 KB 0.00 KB (0.00%)
schema-string.ts 11.12 KB 11.12 KB 0.00 KB (0.00%)
schema-template-literal.ts 15.41 KB 15.41 KB 0.00 KB (0.00%)
schema-toArbitrary.ts 34.10 KB 34.10 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 24.56 KB 24.56 KB 0.00 KB (0.00%)
schema-toCodecJson.ts 19.27 KB 19.27 KB 0.00 KB (0.00%)
schema-toEquivalence.ts 19.38 KB 19.38 KB 0.00 KB (0.00%)
schema-toFormatter.ts 19.49 KB 19.49 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 23.77 KB 23.77 KB 0.00 KB (0.00%)
schema-toRepresentation.ts 19.54 KB 19.54 KB 0.00 KB (0.00%)
schema.ts 19.27 KB 19.27 KB 0.00 KB (0.00%)
stm.ts 12.80 KB 12.80 KB 0.00 KB (0.00%)
stream.ts 9.83 KB 9.83 KB 0.00 KB (0.00%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant