Skip to content

Commit 9ef187c

Browse files
author
Dave Cuthbert
authored
DOCSP-1889 BACKPORT (#1738)
1 parent b11e048 commit 9ef187c

File tree

3 files changed

+156
-25
lines changed

3 files changed

+156
-25
lines changed

source/reference/method/Session.startTransaction.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Definition
4040
that would result in the creation of a new collection.
4141

4242
The :method:`Session.startTransaction()` method can take a document
43-
following options:
43+
with the following options:
4444

4545
.. code-block:: javascript
4646

source/reference/method/Session.txt

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,61 +22,65 @@ Definition
2222
:binary:`~bin.mongosh`, see :method:`Mongo.startSession()`. For more
2323
information on sessions, see :ref:`sessions`.
2424

25+
General Session Methods
26+
~~~~~~~~~~~~~~~~~~~~~~~
27+
2528
.. list-table::
2629

2730
* - Method
2831
- Description
2932

30-
* - .. method:: Session.getDatabase(<database>)
31-
32-
- Access the specified database from the session in :binary:`~bin.mongosh`.
33-
3433
* - .. method:: Session.advanceClusterTime({ clusterTime: <timestamp>, signature: { hash: <BinData>, keyId: <NumberLong> } })
35-
3634
- Updates the cluster time tracked by the session.
3735

3836
* - .. method:: Session.advanceOperationTime(<timestamp>)
39-
4037
- Updates the operation time.
4138

4239
* - .. method:: Session.endSession()
43-
4440
- Ends the session.
4541

46-
* - .. method:: Session.hasEnded()
47-
48-
- Returns a boolean that specifies whether the session has
49-
ended.
50-
5142
* - .. method:: Session.getClusterTime()
52-
5343
- Returns the most recent cluster time as seen by the session.
5444
Applicable for replica sets and sharded clusters only.
5545

56-
* - .. method:: Session.getOperationTime()
46+
* - .. method:: Session.getDatabase(<database>)
47+
- Access the specified database from the session in :binary:`~bin.mongosh`.
5748

49+
* - .. method:: Session.getOptions()
50+
- Access the options for the session. For the available
51+
options, see :method:`SessionOptions`.
52+
53+
* - .. method:: Session.getOperationTime()
5854
- Returns the timestamp of the last acknowledged operation for
5955
the session.
6056

61-
* - .. method:: Session.getOptions()
57+
* - .. method:: Session.hasEnded()
58+
- Returns a boolean that specifies whether the session has
59+
ended.
6260

63-
- Access the options for the session. For the available
64-
options, see :method:`SessionOptions`.
61+
Session Methods for Transactions
62+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6563

66-
* - :method:`Session.startTransaction()`
64+
.. list-table::
6765

68-
- Starts a multi-document transaction for the session. For
69-
details, see :method:`Session.startTransaction()`.
66+
* - Method
67+
- Description
7068

71-
* - :method:`Session.commitTransaction()`
69+
* - :method:`Session.abortTransaction()`
70+
- Aborts the session's transaction. For details, see
71+
:method:`Session.abortTransaction()`.
7272

73+
* - :method:`Session.commitTransaction()`
7374
- Commits the session's transaction. For details, see
7475
:method:`Session.commitTransaction()`.
7576

76-
* - :method:`Session.abortTransaction()`
77+
* - :method:`Session.startTransaction()`
78+
- Starts a multi-document transaction for the session. For
79+
details, see :method:`Session.startTransaction()`.
7780

78-
- Aborts the session's transaction. For details, see
79-
:method:`Session.abortTransaction()`.
81+
* - :method:`Session.withTransaction()`
82+
- Runs a specified lambda function within a transaction. For
83+
details, see :method:`Session.withTransaction()`.
8084

8185
Example
8286
-------
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
.. _session-withTransaction:
2+
3+
==========================
4+
Session.withTransaction()
5+
==========================
6+
7+
.. default-domain:: mongodb
8+
9+
.. contents:: On this page
10+
:local:
11+
:backlinks: none
12+
:depth: 1
13+
:class: singlecol
14+
15+
Definition
16+
----------
17+
18+
.. method:: Session.withTransaction( <function> [, <options> ] )
19+
20+
*New in mongosh v1.1.0*
21+
22+
Runs a specified lambda function within a transaction. If there is an
23+
error, the method retries the:
24+
25+
- commit operation, if there is a failure to commit.
26+
- entire transaction, if the error permits.
27+
28+
The :method:`Session.withTransaction()` method accepts the
29+
`transaction options
30+
<https://mongodb.github.io/node-mongodb-native/4.8/interfaces/TransactionOptions.html>`__.
31+
32+
33+
Behavior
34+
--------
35+
36+
The Node.js driver has a version of ``Session.withTransaction()` that is
37+
known as the `Callback API
38+
<https://www.mongodb.com/docs/drivers/node/current/fundamentals/transactions/#callback-api>`__.
39+
The ``Callback API`` also accepts an callback, however the return type
40+
for the Node.js method must be a Promise. The ``mongosh``
41+
``Session.withTransaction()`` method does not require a Promise.
42+
43+
Example
44+
-------
45+
46+
The following example creates the ``balances`` collection and uses a
47+
transaction to transfer money between two customers.
48+
49+
Create the ``balances`` collection:
50+
51+
.. code-block:: javascript
52+
53+
use accounts
54+
db.balances.insertMany( [
55+
{ customer: "Pat", balance: Decimal128( "35.88" ) },
56+
{ customer: "Sasha", balance: Decimal128( "5.23" ) }
57+
] )
58+
59+
60+
Initialize some variables that are used in the transaction:
61+
62+
.. code-block:: javascript
63+
64+
var fromAccount = "Pat"
65+
var toAccount = "Sasha"
66+
var transferAmount = 1
67+
68+
var dbName = "accounts"
69+
var collectionName = "balances"
70+
71+
Start a session, then run a transaction to update the accounts:
72+
73+
.. code-block:: javascript
74+
75+
var session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
76+
session.withTransaction( async() => {
77+
78+
const sessionCollection = session.getDatabase(dbName).getCollection(collectionName);
79+
80+
// Check needed values
81+
var checkFromAccount = sessionCollection.findOne(
82+
{
83+
"customer": fromAccount,
84+
"balance": { $gte: transferAmount }
85+
}
86+
)
87+
if( checkFromAccount === null ){
88+
throw new Error( "Problem with sender account" )
89+
}
90+
91+
var checkToAccount = sessionCollection.findOne(
92+
{ "customer": toAccount }
93+
)
94+
if( checkToAccount === null ){
95+
throw new Error( "Problem with receiver account" )
96+
}
97+
98+
// Transfer the funds
99+
sessionCollection.updateOne(
100+
{ "customer": toAccount },
101+
{ $inc: { "balance": transferAmount } }
102+
)
103+
sessionCollection.updateOne(
104+
{ "customer": fromAccount },
105+
{ $inc: { "balance": -1 * transferAmount } }
106+
)
107+
108+
} )
109+
110+
The lambda function includes initial checks to validate the operation
111+
before updating the ``balances`` collection.
112+
113+
MongoDB automatically completes the transaction.
114+
115+
- If both ``updateOne()`` operations succeed,
116+
``Session.withTransaction()`` commits the transaction when the callback
117+
returns.
118+
- If an exception is thrown inside the callback,
119+
``Session.withTransaction()`` ends the transaction and rolls back any
120+
uncommitted changes.
121+
122+
.. note::
123+
124+
By default, MongoDB ends transactions that run for more than 60
125+
seconds. If you want to extend the default timeout to experiment with
126+
transactions in :binary:`mongosh`, see :ref:`transaction-limit`.
127+

0 commit comments

Comments
 (0)