Repository navigation
Fix runTx throwing instead of waiting when called while another transaction is active - #468
Conversation
…nsaction is active on the same connection.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #468 +/- ##
==========================================
+ Coverage 84.65% 86.08% +1.43%
==========================================
Files 33 33
Lines 3415 3824 +409
==========================================
+ Hits 2891 3292 +401
- Misses 524 532 +8 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
I'm not sure what the expectation here would be. A single postgres connection is only associated to a single transaction, cannot be in two. Are the users of the package aware of that and would like the library to queue these? Or are they expecting them to overlap? For queueing, the connection pool would be a better place. In fact, I think it should the main place people use. So enabling this may be good, but it also may enable a call pattern which may fail the expectations of the users. What do you think about these concerns? |
|
We expect them to queue, not overlap. The PR keeps one transaction per connection. The second runTx waits for the first to finish. In 3.5.16, the behaviour changed and it now depends on timing. If two runTx calls start in the same microtask, the second waits. That's what the "cannot be interwoven" test covers. If the second call starts one await later, it throws. Queuing in every case or throwing in every case would both be fine with me. |
|
Okay, I'm sold on this. |
3.5.16 added a check to
runTxso that a call made from inside its own callback fails fast instead of deadlocking. That part is good.The check is
_activeTransaction != null, though. That flag is set by any active transaction on the connection. So arunTxissued from a different async flow now throws too. It is not re-entrant, and before 3.5.16 it waited on_operationLock. That is also what therunTxdoc says: "other invocations on a [Connection] are blocked while a transaction is active".The outcome now depends on timing. The existing test "Make sure two simultaneous transactions cannot be interwoven" still passes only because both calls start before the first one sets
_activeTransaction. If the second call comes one query later, it throws:runTxcalls started in the same microtaskrunTxfrom outside, after another transaction beganrunTxfrom inside its own callbackWe hit this in a code generator that shares one
Connectionbetween concurrent workers, each doing a shortrunTx.Fix
runTxnow runs its callback in a zone that records which connections have a transaction callback running. It throws only when the current zone says it is inside this connection's own callback. Every other call waits on_operationLockagain, as before 3.5.16. NestedrunTxcalls on different connections still work.