Repository navigation
Run queries on a connection one at a time so transactions stay on one session - #223
Open
just-some-random-pal wants to merge 1 commit into
Open
just-some-random-pal wants to merge 1 commit into
just-some-random-pal wants to merge 1 commit into
Conversation
… session Every request carries the session the previous response returned, and Connection.execute only stores the new session after the response arrives. Two requests in flight on one connection therefore both send the stale session, and the server treats the second as a new, unrelated session. Inside transaction() that meant a query ran outside the transaction, or COMMIT/ROLLBACK ran on a session with no transaction while the real one stayed open until it timed out, blocking writers. A callback that throws while a query it started is still running hit this on every failure path. Serialize requests per Connection through a FIFO chain. A failed request does not block the ones behind it, so ROLLBACK still runs after a failed query, and COMMIT/ROLLBACK now wait for every query the callback started, awaited or not, and run on the session that query produced. Parallelism across connections is unchanged. Fixes planetscale#191
just-some-random-pal
requested review from
a team and
mattrobenolt
as code owners
October 13, 2026 09:19
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.
Fixes #191.
Every request carries the session the previous response returned, and
Connection.executeonly stores the new session after the response arrives. Two requests in flight on one connection both send the stale session, and the server treats the second as a new session or rejects it with "transaction ... in use". Insidetransaction()that means a query runs outside the transaction, orCOMMIT/ROLLBACKruns on a session with no transaction while the real one stays open until it times out, blocking every writer on the table. The failure path in #191 is the common one: the callback throws while a query it started is still running,ROLLBACKis sent immediately with the pre-query session, and the update's transaction is never rolled back.This serializes requests per
Connectionthrough a FIFO chain, the same approachmysql2takes per connection and the one discussed on #139. Each request now runs after the previous one has settled, so it always carries that response's session. A failed request does not block the ones behind it, soROLLBACKstill runs after a failed query.COMMITandROLLBACKtherefore wait for every query the callback started, awaited or not, and run on the session that query produced.refresh()goes through the same chain.What changes for callers: queries on one
Connectionno longer overlap.Client.executeandClient.transactionalready create a connection per call, andClient.connection()hands out new ones, so parallel work across connections is unaffected.Promise.allover one connection still works, it just runs the queries in order, which is the only order the session protocol can honor. The README's transaction section now says so.Tests, with a fetch that returns a new session per response and can hold a response open: a second query is not sent while the first is in flight and carries its session; a failed query does not block the next; a callback that throws while its query is running sends
ROLLBACKonly after that query completes and with its session; un-awaited inserts run beforeCOMMIT. All four fail onmainand pass with the change. The full suite is 46/46 andnpm run lintis clean.