Repository navigation
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
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>
3221612 to
4ae6d34
Compare
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
Summary by CodeRabbit