-
Type: New Feature
-
Resolution: Unresolved
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Query Optimization
Let's say you're attacking an update with a two-phase commit, colliding on a timestamp field. The second phase uses find_and_modify to ensure the timestamp is the same before applying the update. So far so good. However, should the timestamp be unequal, find_and_modify will simply fail to find, returning no document. In order to take another crack at the update, it's probably necessary to query the record all over again to find out what changed, which is kind of a waste since mongo has (probably) already found the record once before disqualifying it.
An alternate proposal is find_try_modify, basically the opposite of find_and_modify. It returns a document only if the update fails, which should definitely be expressed as an exception by the drivers. For a nice example (in say, python) let's try to $set `resultField` based on data from `documentState` but only if `timestamp` hasn't changed. If it has, we want to look at `documentState` again. The server can assume we want `timestamp` too, since we set it as a collision field. Perhaps setting it as false in the return fields should be permitted, as it is with _id.
try: db.Records.find_try_modify( {_id:578923, $collide:{timestamp:123456789}}}, {$set:{documentState:stateObject}}, {documentState:true} ) except Collision as newState: stateObject = buildUpdate (newState['documentState']) try: # just one more attempt db.Records.find_try_modify( {_id:578923, $collide:{timestamp:newState['timestamp']}}, {$set:{documentState:stateObject}}, {documentState:true} ) except Collision: sendFailureResponse() sendSuccessResponse()