Skip to content

Commit 961ed90

Browse files
committed
DOCS-11505: txn examples for python
1 parent 85171fd commit 961ed90

File tree

5 files changed

+185
-116
lines changed

5 files changed

+185
-116
lines changed

source/core/transactions.txt

Lines changed: 8 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ Clients require MongoDB drivers updated for MongoDB 4.0.
166166
To associate read and write operations with a transaction, you **must**
167167
pass the session to each operation in the transaction.
168168

169+
The following example assumes that the collections exists.
170+
171+
.. include:: /includes/driver-examples/driver-example-transactions-intro-1.rst
172+
173+
Note that the session is passed to each operation in the transaction.
169174

170175
Transactions and the ``mongo`` Shell
171176
------------------------------------
@@ -206,28 +211,7 @@ an element and the transaction as a whole can be retried.
206211
For example, the following helper runs a function and retries the
207212
function if a ``"TransientTransactionError"`` is encountered:
208213

209-
.. code-block:: javascript
210-
211-
// Runs the txnFunc and retries if TransientTransactionError encountered
212-
213-
function runTransactionWithRetry(txnFunc, session) {
214-
while (true) {
215-
try {
216-
txnFunc(session); // performs transaction
217-
break;
218-
} catch (error) {
219-
print("Transaction aborted. Caught exception during transaction.");
220-
221-
// If transient error, retry the whole transaction
222-
if ( error.hasOwnProperty("errorLabels") && error.errorLabels.includes( "TransientTransactionError") ) {
223-
print("TransientTransactionError, retrying transaction ...");
224-
continue;
225-
} else {
226-
throw error;
227-
}
228-
}
229-
}
230-
}
214+
.. include:: /includes/driver-examples/driver-example-transactions-retry-1.rst
231215

232216
Retry Commit Operation
233217
~~~~~~~~~~~~~~~~~~~~~~
@@ -250,107 +234,15 @@ drivers, applications should take measures to handle
250234
For example, the following helper commits a transaction and retries if
251235
a ``"UnknownTransactionCommitResult"`` is encountered:
252236

253-
.. code-block:: javascript
254-
255-
// Retries commit if UnknownTransactionCommitResult encountered
256-
257-
function commitWithRetry(session) {
258-
while (true) {
259-
try {
260-
session.commitTransaction(); // Uses write concern set at transaction start.
261-
print("Transaction committed.");
262-
break;
263-
} catch (error) {
264-
// Can retry commit
265-
if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes( "UnknownTransactionCommitResult") ) {
266-
print("UnknownTransactionCommitResult, retrying commit operation ...");
267-
continue;
268-
} else {
269-
print("Error during commit ...");
270-
throw error;
271-
}
272-
}
273-
}
274-
}
237+
.. include:: /includes/driver-examples/driver-example-transactions-retry-2.rst
275238

276239
Retry Transaction and Commit Operation
277240
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278241

279242
Incorporating logic to retrying the transaction for transient errors
280243
and retrying the commit, the full code example is:
281244

282-
.. code-block:: javascript
283-
284-
// Runs the txnFunc and retries if TransientTransactionError encountered
285-
286-
function runTransactionWithRetry(txnFunc, session) {
287-
while (true) {
288-
try {
289-
txnFunc(session); // performs transaction
290-
break;
291-
} catch (error) {
292-
// If transient error, retry the whole transaction
293-
if ( error.hasOwnProperty("errorLabels") && error.errorLabels.includes("TransientTransactionError") ) {
294-
print("TransientTransactionError, retrying transaction ...");
295-
continue;
296-
} else {
297-
throw error;
298-
}
299-
}
300-
}
301-
}
302-
303-
// Retries commit if UnknownTransactionCommitResult encountered
304-
305-
function commitWithRetry(session) {
306-
while (true) {
307-
try {
308-
session.commitTransaction(); // Uses write concern set at transaction start.
309-
print("Transaction committed.");
310-
break;
311-
} catch (error) {
312-
// Can retry commit
313-
if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes("UnknownTransactionCommitResult") ) {
314-
print("UnknownTransactionCommitResult, retrying commit operation ...");
315-
continue;
316-
} else {
317-
print("Error during commit ...");
318-
throw error;
319-
}
320-
}
321-
}
322-
}
323-
324-
// Updates two collections in a transactions
325-
326-
function updateEmployeeInfo(session) {
327-
employeesCollection = session.getDatabase("hr").employees;
328-
eventsCollection = session.getDatabase("reporting").events;
329-
330-
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
331-
332-
try{
333-
employeesCollection.updateOne( { employee: 3 }, { $set: { status: "Inactive" } } );
334-
eventsCollection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } );
335-
} catch (error) {
336-
print("Caught exception during transaction, aborting.");
337-
session.abortTransaction();
338-
throw error;
339-
}
340-
341-
commitWithRetry(session);
342-
}
343-
344-
// Start a session.
345-
session = db.getMongo("myRepl/mongodb0.example.net:27017,mongodb1.example.net:27017,mongodb2.example.net:27017").startSession( { mode: "primary" } );
346-
347-
try{
348-
runTransactionWithRetry(updateEmployeeInfo, session);
349-
} catch (error) {
350-
// Do something with error
351-
} finally {
352-
session.endSession();
353-
}
245+
.. include:: /includes/driver-examples/driver-example-transactions-retry-3.rst
354246

355247
Atomicity
356248
---------
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.. tabs-drivers::
2+
3+
tabs:
4+
5+
- id: python
6+
content: |
7+
.. class:: copyable-code
8+
.. literalinclude:: /driver-examples/test_examples.py
9+
:language: python
10+
:dedent: 8
11+
:start-after: Start Transactions Intro Example 1
12+
:end-before: End Transactions Intro Example 1
13+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.. tabs-drivers::
2+
3+
tabs:
4+
5+
- id: shell
6+
content: |
7+
.. code-block:: javascript
8+
9+
// Runs the txnFunc and retries if TransientTransactionError encountered
10+
11+
function runTransactionWithRetry(txnFunc, session) {
12+
while (true) {
13+
try {
14+
txnFunc(session); // performs transaction
15+
break;
16+
} catch (error) {
17+
print("Transaction aborted. Caught exception during transaction.");
18+
19+
// If transient error, retry the whole transaction
20+
if ( error.hasOwnProperty("errorLabels") && error.errorLabels.includes( "TransientTransactionError") ) {
21+
print("TransientTransactionError, retrying transaction ...");
22+
continue;
23+
} else {
24+
throw error;
25+
}
26+
}
27+
}
28+
}
29+
30+
- id: python
31+
content: |
32+
.. class:: copyable-code
33+
.. literalinclude:: /driver-examples/test_examples.py
34+
:language: python
35+
:dedent: 8
36+
:start-after: Start Transactions Retry Example 1
37+
:end-before: End Transactions Retry Example 1
38+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.. tabs-drivers::
2+
3+
tabs:
4+
5+
- id: shell
6+
content: |
7+
.. code-block:: javascript
8+
9+
// Retries commit if UnknownTransactionCommitResult encountered
10+
11+
function commitWithRetry(session) {
12+
while (true) {
13+
try {
14+
session.commitTransaction(); // Uses write concern set at transaction start.
15+
print("Transaction committed.");
16+
break;
17+
} catch (error) {
18+
// Can retry commit
19+
if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes( "UnknownTransactionCommitResult") ) {
20+
print("UnknownTransactionCommitResult, retrying commit operation ...");
21+
continue;
22+
} else {
23+
print("Error during commit ...");
24+
throw error;
25+
}
26+
}
27+
}
28+
}
29+
30+
- id: python
31+
content: |
32+
.. class:: copyable-code
33+
.. literalinclude:: /driver-examples/test_examples.py
34+
:language: python
35+
:dedent: 8
36+
:start-after: Start Transactions Retry Example 2
37+
:end-before: End Transactions Retry Example 2
38+
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
.. tabs-drivers::
2+
3+
tabs:
4+
5+
- id: shell
6+
content: |
7+
.. code-block:: javascript
8+
9+
// Runs the txnFunc and retries if TransientTransactionError encountered
10+
11+
function runTransactionWithRetry(txnFunc, session) {
12+
while (true) {
13+
try {
14+
txnFunc(session); // performs transaction
15+
break;
16+
} catch (error) {
17+
// If transient error, retry the whole transaction
18+
if ( error.hasOwnProperty("errorLabels") && error.errorLabels.includes("TransientTransactionError") ) {
19+
print("TransientTransactionError, retrying transaction ...");
20+
continue;
21+
} else {
22+
throw error;
23+
}
24+
}
25+
}
26+
}
27+
28+
// Retries commit if UnknownTransactionCommitResult encountered
29+
30+
function commitWithRetry(session) {
31+
while (true) {
32+
try {
33+
session.commitTransaction(); // Uses write concern set at transaction start.
34+
print("Transaction committed.");
35+
break;
36+
} catch (error) {
37+
// Can retry commit
38+
if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes("UnknownTransactionCommitResult") ) {
39+
print("UnknownTransactionCommitResult, retrying commit operation ...");
40+
continue;
41+
} else {
42+
print("Error during commit ...");
43+
throw error;
44+
}
45+
}
46+
}
47+
}
48+
49+
// Updates two collections in a transactions
50+
51+
function updateEmployeeInfo(session) {
52+
employeesCollection = session.getDatabase("hr").employees;
53+
eventsCollection = session.getDatabase("reporting").events;
54+
55+
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
56+
57+
try{
58+
employeesCollection.updateOne( { employee: 3 }, { $set: { status: "Inactive" } } );
59+
eventsCollection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } );
60+
} catch (error) {
61+
print("Caught exception during transaction, aborting.");
62+
session.abortTransaction();
63+
throw error;
64+
}
65+
66+
commitWithRetry(session);
67+
}
68+
69+
// Start a session.
70+
session = db.getMongo("myRepl/mongodb0.example.net:27017,mongodb1.example.net:27017,mongodb2.example.net:27017").startSession( { mode: "primary" } );
71+
72+
try{
73+
runTransactionWithRetry(updateEmployeeInfo, session);
74+
} catch (error) {
75+
// Do something with error
76+
} finally {
77+
session.endSession();
78+
}
79+
80+
- id: python
81+
content: |
82+
.. class:: copyable-code
83+
.. literalinclude:: /driver-examples/test_examples.py
84+
:language: python
85+
:dedent: 8
86+
:start-after: Start Transactions Retry Example 3
87+
:end-before: End Transactions Retry Example 3
88+

0 commit comments

Comments
 (0)