Repository navigation
fix(mysql): roll back a transaction cancelled during BEGIN - #4468
Open
chenty2333 wants to merge 1 commit into
Open
chenty2333 wants to merge 1 commit into
chenty2333 wants to merge 1 commit into
Conversation
Claim transaction_depth before the BEGIN round trip and add a Rollback guard, as transact-rs#4394 did for Postgres, so a begin() dropped mid-flight queues a ROLLBACK instead of returning the connection to the pool inside a transaction. Fixes transact-rs#4467.
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 #4467
This is the MySQL counterpart of #4394.
MySqlTransactionManager::beginraisedtransaction_depthonly after theBEGINround trip and had no drop guard, so abegin()cancelled during that round trip queued noROLLBACK(start_rollbackis a no-op at depth 0), and the pool handed the connection, still inside the transaction, to the next borrower.The change follows #4394: claim the depth before the round trip, unwind it if the
BEGINdid not take, and add the sameRollbackguard so a dropped future queues aROLLBACKat the claimed depth. With the existingTransaction::dropguard, a cancelled top-levelbegin()now queues exactly oneROLLBACK; at depth 0 the secondstart_rollbackis a no-op. Nestedbegin()now behaves as on Postgres after #4394; the enclosing-level rollback described in #4445 is unchanged by this PR.it_rolls_back_a_transaction_cancelled_during_beginintests/mysql/mysql.rscancelsbegin_with("BEGIN; SELECT SLEEP(2);")after 300 ms, then checks that an autocommit insert through the pool is visible from another connection. It fails onmain(0 rows) and passes with the fix. The MySQL test suite (any,mysql,mysql-rsa,macros,migrate,_unstable-all-types,runtime-tokio,tls-none) passes against MariaDB 11.4;cargo fmtand the CIcargo clippyinvocation are clean.Is this a breaking change?
No. A cancelled top-level
begin()now queues aROLLBACK, and aBEGINthat fails with an error queues one too (as on Postgres since #4394); MySQL acceptsROLLBACKoutside a transaction without an error.