Repository navigation
Conversation
When a statement failed, the driver rolled back the whole user transaction, including the work done before the failed statement, and ended it. MySQL undoes only the failed statement and keeps the transaction active, so the caller can decide whether to commit or roll back the rest. A later COMMIT kept only the work done after the error, and a savepoint created before the error could no longer be used. Roll back only the wrapper transaction of the failed statement. Inside a user transaction, the wrapper is a savepoint, so the transaction stays active. This also keeps an active LOCK TABLES transaction, and replaces the special case for a missing savepoint, since savepoint statements are not wrapped. Part of WordPress#473. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 59 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Summary
Part of #473 (the "Explicit transactions" section).
When a statement fails inside a transaction, the driver rolls back the whole transaction and ends it. MySQL undoes only the failed statement and keeps the transaction active:
The work before the error is lost, and the work after it runs in autocommit mode. A savepoint created before the error is gone too, so
ROLLBACK TO SAVEPOINTfails with error 1305.Fix
Each statement already runs in a wrapper: a transaction when none is active, or a savepoint inside a user transaction. On failure, only that wrapper is now rolled back. This:
INSERT;LOCK TABLES, soUNLOCK TABLEScommits the rows written before the error, as in MySQL;Without a user transaction, the behavior is unchanged: the wrapper transaction is rolled back.
Some SQLite errors roll back the whole transaction automatically (SQLite docs). Then rolling back to the savepoint fails, and the driver ends the transaction as before. This path has no test, because those errors (such as
SQLITE_FULL) are hard to trigger in a unit test.The rest of #473 (error modes and diagnostics) is not part of this PR.
Tests
testFailedStatementKeepsTransactionActivechecks that a failed write and a failed read keep the transaction active, and thatCOMMITkeeps the work before and after them.testFailedStatementIsRolledBackInTransactionchecks that a failed multi-rowINSERTleaves none of its rows.testRollbackToSavepointAfterFailedStatementchecks that a savepoint survives a failed statement.testFailedStatementKeepsTableLockchecks thatUNLOCK TABLESkeeps the rows written before a failed statement.test_failed_query_keeps_transaction_activechecks the same throughPDO::beginTransaction()andPDO::commit().All five fail on
trunk. The existingtestMissingSavepointDoesNotRollbackTransactionstill passes.packages/mysql-on-sqlite: 1048 tests pass (PHP 8.3, SQLite 3.45.1); PHPCS is clean.Use of AI
This change was prepared with Claude Code (Claude Opus 5.5). I reviewed the code, the tests, and this description, and I take responsibility for the change.
Note: this PR and #535 both add tests at the same spot of
WP_MySQL_On_SQLite_PDO_API_Tests.php, so whichever merges second needs a trivial rebase.🤖 Generated with Claude Code