Repository navigation
fix(sqlite): keep transaction depth in sync after SQLite rolls back on its own - #4438
Open
jayzhou2309 wants to merge 2 commits into
Open
jayzhou2309 wants to merge 2 commits into
jayzhou2309 wants to merge 2 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n its own On errors like SQLITE_FULL, SQLite rolls back the whole transaction by itself. The ROLLBACK that SQLx sends when the `Transaction` is dropped then fails, and the depth counter was only decremented on success. The connection kept a stale depth, so a later `begin_with` failed with `InvalidSavePointStatement`. Skip the ROLLBACK statement when SQLite reports no active transaction and still decrement the depth. Fixes transact-rs#4434 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Does your PR solve an issue?
fixes #4434
Is this a breaking change?
No. A
Transactionthat SQLite already rolled back now drops (or callsrollback()) cleanly and leaves the connection at depth 0. Before, itsROLLBACKfailed and left a stale depth behind.commit()on such a transaction still returns SQLite'scannot commit - no transaction is activeerror.Why
On some errors, such as
SQLITE_FULL, SQLite rolls back the whole transaction by itself (sqlite3_get_autocommit). When theTransactionis then dropped, the worker runsROLLBACK, which fails because no transaction is active.Command::Rollbackdecrementedtransaction_depthonly when the statement succeeded, so the connection kept depth 1. The nextbegin_with("BEGIN IMMEDIATE")was rejected withInvalidSavePointStatementbefore it reached SQLite, as the issue reports.The worker now checks
in_transaction()(the same autocommit check the custom-BEGINpath already uses) before it runs the rollback statement. With no active transaction, it skips the statement and still decrements the depth. For nested savepoints, eachTransactionlevel decrements once as it drops, so the depth reaches 0 when the outermost one is gone.Scope
sqlx-sqlite/src/connection/worker.rs:Command::Rollbackskips the rollback statement when SQLite reports no active transaction, and decrements the depth either way.tests/sqlite/sqlite.rs: newit_can_begin_after_sqlite_rolls_back_a_full_transaction, the issue's repro. It forcesSQLITE_FULLwithPRAGMA max_page_count = 2, drops the transaction, raises the limit, then runs and commits aBEGIN IMMEDIATEtransaction.Verification
mainwithattempted to call begin_with at non-zero transaction depthand passes with the fix. It lands in its own commit before the fix.commit()after the auto-rollback still returnscannot commit - no transaction is active.cargo test --no-default-features --features any,macros,migrate,sqlite,_unstable-all-types,runtime-tokiowithDATABASE_URL=sqlite:tests/sqlite/sqlite.db:sqlite45 passed, 1 ignored;sqlite-any3;sqlite-error6;sqlite-describe31;sqlite-types73.cargo test -p sqlx-sqlitepasses.cargo fmt --all -- --checkandcargo clippy -D warningson the pinned 1.94 toolchain: clean onsqlx-sqlite.sqlite-unbundledlinking. The change doesn't depend on runtime or linking.AI disclosure
This PR was written by an AI agent (Claude Code) on behalf of the account owner. The agent reproduced the bug with the new test, wrote the fix and the test, and ran the commands listed under Verification on macOS.
🤖 Written and posted by an AI agent (Claude Code) on behalf of @jayzhou2309.