@@ -203,37 +203,87 @@ content: |
203
203
ref : transactions-stale-reads
204
204
content : |
205
205
206
- Read operations inside a transaction can return stale data. That is,
207
- read operations inside a transaction are not guaranteed to see
208
- writes performed by other committed transactions or
209
- non-transactional writes. For
210
- example, consider the following sequence: 1) a transaction is
211
- in-progress 2) a write outside the transaction deletes a document 3)
212
- a read operation inside the transaction is able to read the
213
- now-deleted document since the operation is using a snapshot from
214
- before the write.
206
+ Read operations inside a transaction can return old data, which is known as a
207
+ :term:`stale read`. Read operations inside a transaction are not guaranteed
208
+ to see writes performed by other committed transactions or
209
+ non-transactional writes. For example, consider the following sequence:
210
+
211
+ #. A transaction is in-progress.
212
+
213
+ #. A write outside the transaction deletes a document.
214
+
215
+ #. A read operation inside the transaction can read the now-deleted document
216
+ since the operation uses a snapshot from before the write operation.
215
217
216
218
To avoid stale reads inside transactions for a single document, you
217
- can use the :method:`db.collection.findOneAndUpdate()` method. For
218
- example:
219
-
220
- .. code-block:: javascript
221
-
222
- session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
223
-
224
- employeesCollection = session.getDatabase("hr").employees;
225
-
226
- employeeDoc = employeesCollection.findOneAndUpdate(
227
- { _id: 1, employee: 1, status: "Active" },
228
- { $set: { employee: 1 } },
229
- { returnNewDocument: true }
230
- );
231
-
232
- - If the employee document has changed outside the transaction, then
233
- the transaction aborts.
219
+ can use the :method:`db.collection.findOneAndUpdate()` method. The following
220
+ :binary:`~bin.mongo` example demonstrates how you can use
221
+ ``db.collection.findOneAndUpdate()`` to take a :term:`write lock` and ensure
222
+ that your reads are up to date:
223
+
224
+ .. procedure::
225
+ :style: normal
226
+
227
+ .. step:: Insert a document into the ``employees`` collection
228
+
229
+ .. code-block:: javascript
230
+ :copyable: true
231
+
232
+ db.getSiblingDB("hr").employees.insertOne(
233
+ { _id: 1, status: "Active" }
234
+ )
235
+
236
+ .. step:: Start a session
237
+
238
+ .. code-block:: javascript
239
+ :copyable: true
240
+
241
+ session = db.getMongo().startSession( { readPreference: { mode: "primary" } } )
242
+
243
+ .. step:: Start a transaction
244
+
245
+ .. code-block:: javascript
246
+ :copyable: true
247
+
248
+ session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } )
249
+
250
+ employeesCollection = session.getDatabase("hr").employees
251
+
252
+ .. step:: Use ``db.collection.findOneAndUpdate()`` inside the transaction
253
+
254
+ .. code-block:: javascript
255
+ :copyable: true
256
+
257
+ employeeDoc = employeesCollection.findOneAndUpdate(
258
+ { _id: 1, status: "Active" },
259
+ { $set: { lockId: ObjectId() } },
260
+ { returnNewDocument: true }
261
+ )
262
+
263
+ Note that inside the transaction, the ``findOneAndUpdate`` operation
264
+ sets a new ``lockId`` field. You can set ``lockId`` field to any
265
+ value, as long as it modifies the document. By updating the
266
+ document, the transaction acquires a lock.
267
+
268
+ If an operation outside of the transaction attempts to modify the
269
+ document before you commit the transaction, MongoDB returns a write
270
+ conflict error to the external operation.
271
+
272
+ .. step:: Commit the transaction
273
+
274
+ .. code-block:: javascript
275
+ :copyable: true
276
+
277
+ session.commitTransaction()
278
+
279
+ After you commit the transaction, MongoDB releases the lock.
280
+
281
+ .. note::
282
+
283
+ If any operation in the transaction fails, the transaction
284
+ aborts and all data changes made in the transaction are discarded
285
+ without ever becoming visible in the collection.
234
286
235
- - If the employee document has not changed, the transaction returns
236
- the document and locks the document.
237
287
---
238
288
ref : transactions-read-concern-majority
239
289
content : |
0 commit comments