如何从.net类处理多线程MongoDb更新?

时间:2014-04-17 19:54:48

标签: mongodb mongodb-.net-driver

MongoDb,c#驱动程序:两个线程从MongoDb获取相同的单个文档,更改其状态并将其更新回数据库。我希望每个线程都能检测读取和更新此文档之间的其他线程是否进行了任何更改。如果这些更改是由其他线程完成的,我不希望当前线程覆盖它们,我想记录此信息。请让我知道可能的解决方案。我知道有MongoCollection<T>.UpdateMongoCollection<T>.FindAndModify方法,我可以根据从Db获取的信息定义查询,但是我没有看到任何方法来检测文档是否实际被发现和更新,那里没有更新返回的记录数量等信息。

1 个答案:

答案 0 :(得分:5)

根据我的理解,您需要optimistic locking

实现乐观锁定的一种简单方法是对文档进行版本化并在每次更新时增加版本号,即

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));
}

现在让我们假设两个线程A和B同时执行操作:

  • 读取文档ID 8,版本= 5
  • B读取文档ID 8,版本= 5
  • B商店更新ID 8,版本= 6
  • 尝试在文档ID 8,版本5上存储更新,但此类对象不再存在。

MongoCollection<T>.Update会返回WriteConcernResult,其中包含一个属性DocumentsAffected,可用于检查文档是否已更新。

另请参阅MongoDB文档:Isolate Sequence of Operations