Repository navigation
Conversation
The wasm driver tracked the transaction itself in `_inTx`. SQLite ends a transaction on its own after SQLITE_FULL, SQLITE_IOERR or SQLITE_BUSY, and the flag then latched: the next savepoint skipped its `BEGIN`, and releasing it threw "cannot commit - no transaction is active". `inTransaction` now reads `sqlite3_get_autocommit`, which the wasm build binds but does not type — hence the cast, and the check at init that it is there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Without the `pointer` guard, `sqlite3_get_autocommit(undefined)` returns 0 and a closed connection reports a transaction open. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…egins Review follow-up. Reading `inTransaction` from SQLite drops the invariant the cached flag carried, that no transaction implies an empty savepoint stack. When SQLite ends a transaction itself, the stale stack makes `commitIfNeeded` defer to a savepoint owner that no longer exists, and the next write sits in a transaction nobody closes. The Node driver has read better-sqlite3's live `inTransaction` all along and had the same hole; both are fixed, and both mocks now move the flag the way SQLite does. The capi check moves above the open so a build without `sqlite3_get_autocommit` does not leak the handle, and `inTransaction` is no longer `configurable`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…hods `createSavepoint`, `rollbackSavepoint` and `releaseSavepoint` were byte-for-byte identical in both drivers, and after the last change so were the three transaction helpers under them. The drivers now differ only in how they run a prepared statement, which is what they inject. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review follow-up. Both driver suites had `releaseSavepoint removes all points after target` and the extracted suite did not, so `splice(idx, 1)` there passed everything — which would leave the crank's outermost release with a non-empty stack and its transaction unowned. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 15, 2026
sirtimid
added this pull request to stack #1109
September 15, 2026 22:42
# Conflicts: # packages/kernel-store/CHANGELOG.md
…-transaction-helpers
A wasm write that failed with SQLITE_FULL left its prepared statement unreset, and SQLite refuses to bind one in that state, so every later call to the same operation threw SQLITE_MISUSE. The kv and vatstore statements now reset in `finally`, as `getKVData` and `executeQuery` already did. The real-SQLite tests now end the transaction with a real SQLITE_FULL instead of a hand-issued `ROLLBACK TRANSACTION`, which never failed a statement and so could not see this. A new Node test runs the savepoint stack clear against real better-sqlite3, and the changelog says what `main` actually did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n' into sirtimid/sqlite-transaction-helpers # Conflicts: # packages/kernel-store/src/sqlite/nodejs.test.ts # packages/kernel-store/src/sqlite/wasm.test.ts # packages/kernel-store/src/sqlite/wasm.ts
Contributor
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||
A COMMIT that fails and leaves the transaction open (SQLITE_BUSY, a deferred foreign key) stays busy until reset, and the connection keeps a read lock past the ROLLBACK that ends the transaction: DROP TABLE fails with SQLITE_LOCKED until the next COMMIT. `runStatement` now resets in a `finally`, as the kv and vatstore statements already do, and `kvClear` goes through it. The local `PreparedStatement` type gives way to the one sqlite-wasm declares. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w found untested - The `TransactionalDatabase` docstring now says why `_spStack` dropping a rolled-back name is safe: no name is opened twice on the stack. - `rollbackSavepoint`'s catch no longer claims a failed rollback discards only what it was abandoning; it discards the savepoints below too. - New tests: a repeated name resolves to its newest savepoint; `beginIfNeeded` reports that it began; the abort is attempted when the rollback fails. `vatStore.updateKVData`'s begin and commit assertions now check the BEGIN and COMMIT statements rather than the kv one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1005 entry Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sirtimid
added a commit
that referenced
this pull request
Oct 9, 2026
Conflicts: the changelog keeps #1092's wasm COMMIT entry and drops #1089's Node entry, which this branch replaces; the corrected `rollbackSavepoint` comment sits above `discardTransaction('rollback')`; the fake driver is this branch's, with `abort` destructured where #1092 restored its assertion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Node and wasm drivers carried the same six transaction and savepoint methods,
beginIfNeeded,commitIfNeeded,rollbackIfNeeded,createSavepoint,rollbackSavepointandreleaseSavepoint, differing only in how a prepared statement runs.They move into the internal
sqlite/transactions.ts, built bymakeTransactionMethods({ db, begin, commit, abort }), and each driver injects its three statement runners.TransactionalDatabasedocstring records where_spStackand SQLite's savepoint stack disagree, as Extract the duplicated sqlite savepoint methods into one module #1013 asks, and why that is safe: no name is opened twice on the stack.runStatementresets in afinally. A COMMIT that failed with the transaction left open stayed busy, so the connection kept a read lock past the ROLLBACK that followed.rollbackSavepointcomment, and the fix(ocap-kernel): report a dead run loop instead of a healthy kernel #1005 changelog entry, no longer claim a failed rollback discards only what it was abandoning.Testing
transactions.test.ts, against a fake database.beginIfNeeded,commitIfNeededandrollbackIfNeededget direct tests there, and a repeated name resolves to its newest savepoint.finallythe drop hitsSQLITE_LOCKED.vatStore.updateKVData's begin and commit assertions check the BEGIN and COMMIT statements; they were checking the kv statement.Closes #1013
🤖 Generated with Claude Code
Note
Medium Risk
Changes shared persistence transaction/savepoint behavior for both drivers; the wasm COMMIT-reset fix alters lock lifecycle after errors, though behavior is heavily tested.
Overview
Unifies SQLite transaction and savepoint handling across the Node (
better-sqlite3) and wasm drivers by movingbeginIfNeeded,commitIfNeeded,rollbackIfNeeded, and the three savepoint APIs into sharedmakeTransactionMethodsinsqlite/transactions.ts. Each driver only supplies how it runs its preparedBEGIN/COMMIT/ROLLBACKstatements.The wasm driver now runs those statements (and clear) through a
runStatementhelper that always resets afterstep(), fixing a case where a failed COMMIT left the statement busy and held a read lock soDROP TABLE/VACUUMfailed until the next commit (#1092).Tests: duplicated savepoint suites in
nodejs.test.tsandwasm.test.tsare replaced bytransactions.test.tsagainst a fake DB; each driver keeps one test that its own prepared statements are invoked. Integration coverage adds the post-failed-COMMITDROP TABLEscenario inwasm.transactions.test.ts. Changelog wording for failedrollbackSavepointis clarified.Reviewed by Cursor Bugbot for commit be53378. Bugbot is set up for automated code reviews on this repo. Configure here.