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