Skip to content

Commit ac593ba

Browse files
author
Dave Cuthbert
authored
Docsp 18899 transactions in session api (#1724)
* Needs example * DOCS-18899 transactions in a session * DOCSP-18899 transactions in session api * DOCSP-18899 transactions in session * DOCSP-18899 transactions in session * DOCSP-18899 transactions in session * DOCSP-18899 transactions in session * Review feedback * Review feedback * Review feedback * Review feedback * Review feedback * Staging fixes
1 parent 2c64ee5 commit ac593ba

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
@@ -20,61 +20,65 @@ Definition
2020
:binary:`~bin.mongosh`, see :method:`Mongo.startSession()`. For more
2121
information on sessions, see :ref:`sessions`.
2222

23+
General Session Methods
24+
~~~~~~~~~~~~~~~~~~~~~~~
25+
2326
.. list-table::
2427

2528
* - Method
2629
- Description
2730

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

3634
* - .. method:: Session.advanceOperationTime(<timestamp>)
37-
3835
- Updates the operation time.
3936

4037
* - .. method:: Session.endSession()
41-
4238
- Ends the session.
4339

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

54-
* - .. method:: Session.getOperationTime()
44+
* - .. method:: Session.getDatabase(<database>)
45+
- Access the specified database from the session in :binary:`~bin.mongosh`.
5546

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

59-
* - .. method:: Session.getOptions()
55+
* - .. method:: Session.hasEnded()
56+
- Returns a boolean that specifies whether the session has
57+
ended.
6058

61-
- Access the options for the session. For the available
62-
options, see :method:`SessionOptions`.
59+
Session Methods for Transactions
60+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6361

64-
* - :method:`Session.startTransaction()`
62+
.. list-table::
6563

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

69-
* - :method:`Session.commitTransaction()`
67+
* - :method:`Session.abortTransaction()`
68+
- Aborts the session's transaction. For details, see
69+
:method:`Session.abortTransaction()`.
7070

71+
* - :method:`Session.commitTransaction()`
7172
- Commits the session's transaction. For details, see
7273
:method:`Session.commitTransaction()`.
7374

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

76-
- Aborts the session's transaction. For details, see
77-
:method:`Session.abortTransaction()`.
79+
* - :method:`Session.withTransaction()`
80+
- Runs a specified lambda function within a transaction. For
81+
details, see :method:`Session.withTransaction()`.
7882

7983
Example
8084
-------
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)