[DRIVERS-2471] Run abortTransaction when commitTransaction in withTransaction times out Created: 13/Oct/22 Updated: 16/Dec/22 |
|
| Status: | Backlog |
| Project: | Drivers |
| Component/s: | Transactions |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Unknown |
| Reporter: | Benji Rewis (Inactive) | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||
| Driver Changes: | Needed | ||||||||
| Description |
SummaryIn the sequence of actions section of the convenient transactions API (see step 9), we never run abortTransaction when commitTransaction fails. This may be because a failed commit may unpin the session and the abort may run on a different mongos in sharded clusters. If commitTransaction times out (either due to default withTransaction timeout or a CSOT timeout), the transaction will not be committed and will not be aborted. This means no new transaction can be started on the session and other transactions on other sessions may encounter write conflicts. Should we reconsider running abortTransaction if commitTransaction fails with a non-retryable error in withTransaction? MotivationWho is the affected end user?Users of the convenient transactions API (particularly when using timeouts). How does this affect the end user?Potential write conflicts and unexpected session errors. How likely is it that this problem or use case will occur?A little unlikely. For the case of timeouts, the timeout would have to occur after the callback's operations but before commitTransaction finishes. If the problem does occur, what are the consequences and how severe are they?Potential write conflicts and unexpected session errors. Is this issue urgent?No. Is this ticket required by a downstream team?mongosync brought up this issue in the Go driver (see related issue). Is this ticket only for tests?No. |
| Comments |
| Comment by Benji Rewis (Inactive) [ 26/Oct/22 ] | |
|
I realize this is a pretty niche case, but we are fixing this in the Go driver (see related Go driver ticket). I'm wondering if we could just add one step between 7 and 8 in the sequence of actions with something like:
Once commitTransaction is invoked in the current step 8, a client-side timeout does not definitively mean the transaction was not committed server-side, so I think after that point, our only choice is to potentially retry commitTransaction. | |
| Comment by Benji Rewis (Inactive) [ 13/Oct/22 ] | |
Oh interesting, do drivers automatically abort the previous in-progress transaction? Or is that logic on the server? Calling startTransaction twice in a row on the same session in the Go driver does return a client-side error ErrTransactInProgress.
Yep, that's the scenario. | |
| Comment by Shane Harvey [ 13/Oct/22 ] | |
This part is not true, IIRC starting a new transaction on the same session will automatically abort the previous transaction (if it's still open).
I believe we could only run abortTransaction if the commitTransaction was never even attempted (otherwise the session will raise this error: "Cannot call abortTransaction after calling commitTransaction"). If commitTransaction was attempted and failed then we can only retry by calling commitTransaction again. Could you describe the exact scenario in a little more detail? Is it that commitTransaction is called and then fails with a client side timeout error before sending the commit command to the server? |