Skip to content

Commit ec32686

Browse files
author
Divjot Arora
authored
DRIVERS-1655 Unpin sessions after all abortTransaction attempts (#968)
1 parent 9ed52dd commit ec32686

File tree

4 files changed

+100
-23
lines changed

4 files changed

+100
-23
lines changed

source/transactions/tests/unified/mongos-unpin.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,55 @@
185185
}
186186
]
187187
},
188+
{
189+
"description": "unpin after non-transient error on abort",
190+
"operations": [
191+
{
192+
"name": "startTransaction",
193+
"object": "session0"
194+
},
195+
{
196+
"name": "insertOne",
197+
"object": "collection0",
198+
"arguments": {
199+
"document": {
200+
"x": 1
201+
},
202+
"session": "session0"
203+
}
204+
},
205+
{
206+
"name": "targetedFailPoint",
207+
"object": "testRunner",
208+
"arguments": {
209+
"session": "session0",
210+
"failPoint": {
211+
"configureFailPoint": "failCommand",
212+
"mode": {
213+
"times": 1
214+
},
215+
"data": {
216+
"failCommands": [
217+
"abortTransaction"
218+
],
219+
"errorCode": 91
220+
}
221+
}
222+
}
223+
},
224+
{
225+
"name": "abortTransaction",
226+
"object": "session0"
227+
},
228+
{
229+
"name": "assertSessionUnpinned",
230+
"object": "testRunner",
231+
"arguments": {
232+
"session": "session0"
233+
}
234+
}
235+
]
236+
},
188237
{
189238
"description": "unpin when a new transaction is started",
190239
"operations": [

source/transactions/tests/unified/mongos-unpin.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,23 @@ tests:
9393
- *abortTransaction
9494
- *assertNoPinnedServer
9595

96+
- description: unpin after non-transient error on abort
97+
operations:
98+
- *startTransaction
99+
- *insertOne
100+
- name: targetedFailPoint
101+
object: testRunner
102+
arguments:
103+
session: *session0
104+
failPoint:
105+
configureFailPoint: failCommand
106+
mode: { times: 1 }
107+
data:
108+
failCommands: [ abortTransaction ]
109+
errorCode: 91 # ShutdownInProgress
110+
- *abortTransaction
111+
- *assertNoPinnedServer
112+
96113
- description: unpin when a new transaction is started
97114
operations:
98115
- *startTransaction

source/transactions/transactions.rst

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Driver Transactions Specification
33
=================================
44

55
:Spec Title: Driver Transactions Specification
6-
:Spec Version: 1.5.5
6+
:Spec Version: 1.5.6
77
:Author: Shane Harvey
88
:Spec Lead: A\. Jesse Jiryu Davis
99
:Advisory Group: A\. Jesse Jiryu Davis, Matt Broadstone, Robert Stam, Jeff Yemin, Spencer Brody
@@ -810,26 +810,32 @@ certain retries of commitTransaction and abortTransaction) to the same mongos.
810810
When to unpin
811811
^^^^^^^^^^^^^
812812

813-
Drivers MUST unpin a ClientSession when a command within a transaction,
814-
including commitTransaction and abortTransaction, fails with a
815-
TransientTransactionError. Transient errors indicate that the transaction
816-
in question has already been aborted or that the pinned mongos is
817-
down/unavailable. Unpinning the session ensures that a subsequent
818-
abortTransaction (or commitTransaction) does not block waiting on a server
819-
that is unreachable.
820-
821-
Additionally, drivers MUST unpin a ClientSession when any individual
822-
commitTransaction command attempt fails with an UnknownTransactionCommitResult
823-
error label. In cases where the UnknownTransactionCommitResult causes an
824-
automatic retry attempt, drivers MUST unpin the ClientSession before performing
825-
server selection for the retry.
826-
827-
Aborting a transaction or starting a new transaction on a pinned
828-
ClientSession MUST unpin the session. Committing a transaction on a pinned
829-
ClientSession MUST NOT unpin the session as commitTransaction may be called
830-
multiple times. Additionally, any non-transaction operation using a pinned
831-
ClientSession MUST unpin the session and the operation MUST perform normal
832-
server selection.
813+
Drivers MUST unpin a ClientSession in the following situations:
814+
815+
#. The transaction is aborted. The session MUST be unpinned regardless of
816+
whether or the ``abortTransaction`` command succeeds or fails, or was
817+
executed at all. If the operation fails with a retryable error, the
818+
session MUST be unpinned before performing server selection for the retry.
819+
#. Any operation in the transcation, including ``commitTransaction`` fails with
820+
a TransientTransactionError. Transient errors indicate that the
821+
transaction in question has already been aborted or that the pinnned
822+
mongos is down/unavailable. Unpinning the session ensures that a
823+
subsequent ``abortTransaction`` (or ``commitTransaction``) does not block
824+
waiting on a server that is unreachable.
825+
#. Any ``commitTransaction`` attempt fails with an
826+
``UnknownTransactionCommitResult`` error label. If the error is also
827+
considered retryable, the session MUST be unpinned before performing
828+
server selection for the retry.
829+
#. A new transaction is started on the ClientSession after the previous
830+
transaction has been committed. The session MUST be unpinned before
831+
performing server selection for the first operation of the new
832+
transaction.
833+
#. A non-transactional operation is performed using the ClientSession. The
834+
session MUST be unpinned before performing server selection for the
835+
operation.
836+
837+
Note that committing a transaction on a pinned ClientSession MUST NOT unpin
838+
the session as ``commitTransaction`` may be called multiple times.
833839

834840
recoveryToken field
835841
~~~~~~~~~~~~~~~~~~~
@@ -1400,6 +1406,8 @@ durable, which achieves the primary objective of avoiding duplicate commits.
14001406
**Changelog**
14011407
-------------
14021408

1409+
:2020-04-07: Clarify that all abortTransaction attempts should unpin the session,
1410+
even if the command is not executed.
14031411
:2020-04-07: Specify that sessions should be unpinned once a transaction is aborted.
14041412
:2019-10-21: Specify that a commit error can have two error labels
14051413
:2019-07-30: Clarify when the cached recoveryToken should be cleared.

source/unified-test-format/tests/Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
SCHEMA=../schema-1.3.json
22

3-
.PHONY: all invalid valid-fail valid-pass versioned-api load-balancers gridfs HAS_AJV
3+
.PHONY: all invalid valid-fail valid-pass versioned-api load-balancers gridfs transactions HAS_AJV
44

5-
all: invalid valid-fail valid-pass versioned-api load-balancers gridfs
5+
all: invalid valid-fail valid-pass versioned-api load-balancers gridfs transactions
66

77
invalid: HAS_AJV
88
@# Redirect stdout to hide expected validation errors
@@ -23,6 +23,9 @@ load-balancers: HAS_AJV
2323
gridfs: HAS_AJV
2424
@ajv test -s $(SCHEMA) -d "../../gridfs/tests/*.yml" --valid
2525

26+
transactions: HAS_AJV
27+
@ajv test -s $(SCHEMA) -d "../../transactions/tests/unified/*.yml" --valid
28+
2629
HAS_AJV:
2730
@if ! command -v ajv > /dev/null; then \
2831
echo 'Error: need "npm install -g ajv-cli"' 1>&2; \

0 commit comments

Comments
 (0)