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