YMC
YMC

Reputation: 5452

How to handle multithreading MongoDb updates from .net classes?

MongoDb, c# driver: Two threads are taking the same single document from MongoDb, changing its state and updating it back to database. I want every thread to detect if any changes were done by other thread between moments of reading and updating this document. If such changes are done by other thread, I do not want current thread to override them and I want to log this information. Please let me know possible solutions for that. I know there is MongoCollection<T>.Update and MongoCollection<T>.FindAndModify methods, where I can define query based on information taken from Db, but I do not see any ways to detect if the document was actually found and updated or not, there is no information like number of records updated returned.

Upvotes: 3

Views: 1473

Answers (1)

mnemosyn
mnemosyn

Reputation: 46291

From what I understand, you want optimistic locking.

A straightforward way to implement optimistic locking is to version your documents and increase the version number with every update, i.e.

public void Update(MyClass document)
{
    db.GetCollection<MyClass>("MyClass").Update(
        Query.And(
            Query<MyClass>.EQ(p => p.Id, document.Id), 
            Query<MyClass>(p => p.Version, document.Version),
            Update<MyClass>.Replace(document).Inc(p => p.Version));
}

Now let's suppose two threads A and B perform operations concurrently:

  • A read document id 8, version = 5
  • B read document id 8, version = 5
  • B store update id 8, version = 6
  • A attempt to store update on document id 8, version 5, but such an object no longer exists.

MongoCollection<T>.Update returns a WriteConcernResult which has a property DocumentsAffected that you can use to check whether a document was updated, or not.

Also see the MongoDB docs: Isolate Sequence of Operations

Upvotes: 5

Related Questions