fix: only update emulated transaction state when the statement succeeds - #1767
fix: only update emulated transaction state when the statement succeeds#1767arthurschreiber wants to merge 2 commits into
Conversation
With TDS versions below 7.2, transactions are emulated with SQL batches and client-side `transactionDepth`/`inTransaction` bookkeeping. That bookkeeping was updated unconditionally - a `BEGIN TRAN`/`COMMIT TRAN`/ `ROLLBACK TRAN`/`SAVE TRAN` batch that failed (a server error, or a request that failed before being sent: `EINVALIDSTATE`, `ECANCEL`, `ECLOSE`) still incremented or decremented the counters, leaving the client state out of sync with the server. Only update the counters when the statement actually succeeded. The pre-existing rule that a failed SQL batch clears `inTransaction` on these TDS versions (mirroring the server aborting the transaction on a batch error) is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
ReviewThis is a clean, well-scoped fix. Verified the diff against the surrounding code in Correctness
One edge case worth a mention (not new to this PR, but sharpened by it) Tests
Style/scope
No security or performance concerns — this only touches in-memory counter bookkeeping on the error path of a pre-existing legacy code path. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c63727eb52
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1767 +/- ##
==========================================
+ Coverage 80.71% 80.81% +0.10%
==========================================
Files 90 90
Lines 4880 4885 +5
Branches 927 931 +4
==========================================
+ Hits 3939 3948 +9
+ Misses 643 638 -5
- Partials 298 299 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ction On TDS versions below 7.2, a batch error aborts the entire transaction on the server, and the end-of-message handling already cleared `inTransaction` to match - but left `transactionDepth` untouched, producing an internally inconsistent state (`inTransaction === false` with a positive depth) that a later transaction would build on. Reset the depth together with the flag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ReviewSolid, well-scoped fix. The core change — guarding the four legacy-path ( I traced the interaction between the two commits to be sure they compose correctly: for Possible follow-up (out of scope, but same bug class)
Test coverageThe new Nits
Overall: correct, well-tested, appropriately narrow in scope. Approve modulo the optional |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fbb91ce520
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Superseded by #1768: rather than hardening the TDS 7.1 emulated transaction bookkeeping against cancellation races that are fundamentally unresolvable client-side (see the review threads), TDS 7.1 is now deprecated, and support - including this entire code path - will be removed in the next major version. Two pieces of this work survive elsewhere:
Generated by Claude Code |
Summary
With TDS versions below 7.2, transactions are emulated with SQL batches and client-side
transactionDepth/inTransactionbookkeeping. That bookkeeping was updated unconditionally: aBEGIN TRAN/COMMIT TRAN/ROLLBACK TRAN/SAVE TRANbatch that failed — with a server error, or before ever being sent (EINVALIDSTATE,ECANCEL,ECLOSE) — still incremented or decremented the counters, leaving the client-side transaction state out of sync with the server.This guards the four legacy-path callbacks with
if (!err), so the counters only move when the statement actually succeeded.Extracted from #1766, where it was flagged by review as an independent, pre-existing bug fix that deserves its own release entry rather than shipping silently inside a feature. #1766 will be rebased to drop its copy of these hunks once this merges.
What is deliberately unchanged
The pre-existing rule in the end-of-message handling that a failed SQL batch clears
inTransactionon these TDS versions (mirroring the server aborting the transaction on a batch error) is left as is — this PR only fixes the counter updates for statements that failed.Testing
New
test/unit/transaction-state-test.tsusing the fake-server pattern, negotiating TDS 7.1 (with the pre-7.2 wire formats — 32-bitDONErow count, 16-bitERRORline number):BEGIN TRANthat fails with a server error leavestransactionDepth/inTransactionuntouched,BEGIN TRANupdates them,COMMIT TRANrejected withEINVALIDSTATE(attempted while another request is in flight, so it fails before anything is sent) leaves them untouched.Verified the test fails without the guards.
npm test: 433 passing, 0 failingnpx eslint src test+tsc: clean🤖 Generated with Claude Code
Generated by Claude Code