Parallel findAndModify queries successfully update the same document

I have a working task written in Java and using the MongoDB 3.4 replica set that launches many threads, each of which does this essentially.

  • Run task
  • Signal of completion of this task by updating the document for this task in MongoDB
  • Run a query to check if all tasks in this task set are completed
    • If yes, proceed to the next processing step.
    • Otherwise do nothing

As you can see, there is a race condition; several tasks may end at about the same time and think that they are the last task to complete. I want to use MongoDB to make sure that only one of these tasks allows us to start the next processing step.

I have the following code designed to continue only one of these tasks (I use Jongo to interact with MongoDB).

Chipset modified = chipsets
  .findAndModify("{_id: #, status: {$ne: #}}", new Object[] { chipset.getId(), Chipset.Status.Queued })
  .with("{$set: {status: #}}", new Object[] { Chipset.Status.Queued })
  .returnNew().as(Chipset.class);

if (modified != null)
    runNextProcessingStep();

Pretty simple here; I just use findAndModify to change the chipset status (task set) to Queued. The one that makes the change successfully gets runNextProcessingStep () done.

Or, as I think it should work. In fact, several tasks, even those that end at a distance of 2 seconds, somehow return a nonzero value modified. As far as I understand, MongoDB should block the document when findAndModify starts, so that a non-empty document can be returned no more than once.

findAndModify . Linearizable. _id status. . , , findAndModify? ?

+4
1

, , , , . , - . , , , , . findAndModify , , .

+1

Source: https://habr.com/ru/post/1694154/


All Articles