Details
Description
The WorkingSetMember is transitioned into the OWNED_OBJ state prior to the deletion of the document from the collection.
if (_params.returnDeleted) {
|
// Save a copy of the document that is about to get deleted.
|
BSONObj deletedDoc = member->obj.value();
|
member->obj.setValue(deletedDoc.getOwned());
|
member->loc = RecordId();
|
member->transitionToOwnedObj();
|
}
|
Consider the following sequence of events:
- The user does {findAndModify: 'coll', query: {}, remove: true}}.
- The child of the DeleteStage advances and the corresponding WorkingSetMember is in the LOC_AND_OBJ state.
- We intend to return the delete document, so the WorkingSetMember is transitioned into the OWNED_OBJ state.
- Collection::deleteDocument() is called and throws a WriteConflictException.
- The WorkingSetID of the WorkingSetMember is saved in _idRetrying and the DeleteStage returns NEED_YIELD.
- DeleteStage::work() is called again and status is set to ADVANCED and the id is set to _idRetrying.
- The WorkingSetMember is in the OWNED_OBJ state and therefore returns false when member->hasLoc() is called.
- nInvalidateSkips is incremented and the DeleteStage returns NEED_TIME.
Thus, we won't actually retry deleting the document if a WriteConflictException occurred. Instead, we should transition the WorkingSetMember to the OWNED_OBJ state after the delete occurs.
Attachments
Issue Links
- is related to
-
SERVER-16063 Rewrite findAndModify
-
- Closed
-