我有一个电子邮件通知集合,将由多个线程访问。我需要通过当前线程锁定一些记录,以便我可以专门使用它们。
我的收藏如下:
public class EmailNotification
{
[BsonId]
public string Id { get; set; }
public DateTime CreatedAt { get; set; }
public string LockedBy { get; set; }
public DateTime? LockedUntil { get; set; }
public int Priority { get; set; }
...
}
我的想法是先通过更新“LockedBy”和“LockedUntil”字段来“软锁”记录(因此利用mongoDB更新锁定),然后在第二步检索我已经软锁定的记录。与他们合作。
我在第一步遇到麻烦。我需要使用更新命令锁定“N个最紧迫的电子邮件”。这意味着我需要找到所有将“LockedUntil”字段设置为null或过去的值的记录,按“优先级”(desc)然后按“CreatedAt”(asc)排序,并仅更新在单个命令中由此产生的前N条记录,以实现软锁定而不会遇到并发问题。
我正在尝试从C#方法执行此操作,因此必须使用CSharp驱动程序。有没有办法用最新版本的驱动程序(2.6)来完成我需要的东西?
答案 0 :(得分:0)
您无法在单个原子更新中更新多个文档 命令:
在MongoDB中,写操作,例如db.collection.update() db.collection.findAndModify(),db.collection.remove()是原子的 单个文档的级别。对于必须更新的字段 在一起,将字段嵌入同一文档中可确保这一点 这些字段可以原子方式更新。
http://docs.mongodb.org/manual/tutorial/model-data-for-atomic-operations/
如果您尝试实现此锁定模式,则在更新所有更新命令之前,您将面临另一个进程/线程的风险。
你可以改为使用findandmodify调用来循环锁定和检索一个文档。
FindAndModify方法
如果要查找匹配的文档并进行更新,请使用FindAndModify 它在一个原子操作中。 FindAndModify始终更新单个 文档,您可以组合匹配多个文档的查询 使用排序标准来确定哪个匹配 文件已更新。另外,FindAndModify将返回 匹配文档(在更新之前或之后)和if 您希望可以指定匹配文档的哪些字段 返回。
findAndModify可以通过C#驱动程序获得,它的用法如下:
http://docs.mongodb.org/ecosystem/tutorial/use-csharp-driver/