Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-5951

find_try_modify and $collide operator to streamline two-phase commit

    • Type: Icon: New Feature New Feature
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Querying, Write Ops
    • Labels:
    • 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()
       

            Assignee:
            backlog-query-optimization [DO NOT USE] Backlog - Query Optimization
            Reporter:
            khabok Jason Voorhees
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: