Skip to content

Conversation

@stevensJourney
Copy link
Collaborator

@stevensJourney stevensJourney commented Nov 19, 2025

Problem

A db transaction death-loop could occur when using IndexedDB across multiple tabs, manifesting as the error:

cannot start a transaction within a transaction

This happens when a tab holding an active SQLite transaction is closed before committing or rolling back that transaction. Since IndexedDB shares a single SQLite connection (via a shared web worker) across all tabs, the uncommitted transaction persists and blocks subsequent transaction attempts.

Root Cause

  • Each tab shares its SQLite connection with the shared sync worker
  • The shared DBAdapter can be closed during an active transaction (e.g., when a tab closes)
  • Uncommitted transactions remain active on the shared connection
  • Subsequent BEGIN statements fail because a transaction is already in progress

Solution

This PR implements a connection "hold" mechanism:

  1. Hold acquisition: A hold is created when a worker starts using a connection
  2. Hold release: The hold is released when work completes normally
  3. Orphaned hold detection: If the shared worker detects a hold changed without being properly released (indicating the tab closed mid-transaction), it executes ROLLBACK to clean up the orphaned transaction

This ensures transactions are always resolved, even when tabs close unexpectedly.

@changeset-bot
Copy link

changeset-bot bot commented Nov 19, 2025

🦋 Changeset detected

Latest commit: 8fc41a8

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

This PR includes changesets to release 2 packages
Name Type
@powersync/web Patch
@powersync/diagnostics-app 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

@stevensJourney stevensJourney marked this pull request as ready for review November 20, 2025 09:23
Copy link
Contributor

@rkistner rkistner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy with the overall approach - just have a minor comment on the holds that may affect performance.

@stevensJourney stevensJourney merged commit e88154e into main Nov 20, 2025
9 of 12 checks passed
@stevensJourney stevensJourney deleted the indexeddb-holds branch November 20, 2025 14:38
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.

3 participants