有没有办法在MongoDB中原子地更新两个集合? [英] Is there any way to atomically update two collections in MongoDB?

查看:366
本文介绍了有没有办法在MongoDB中原子地更新两个集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组邮件:

  {
messageid:ObjectId
userid:ObjectId
message:string
isread:true | false
}

每个用户的邮件数量集合:

  {
userid:ObjectId
total:int
未读:int
}

当我从邮件集合中删除邮件时,还需要减少计数集合中的总计,并有条件地(如果messages.isread== false)减少未读字段。



我需要先检索teh消息,检查其isread字段,然后更新计数。有可能该消息将被标记为在这些动作之间读取,然后我将减少未读计数不正确。



有没有办法根据其他集合的结果在一个集合中有条件地更改某个集合?

解决方案

这里有很多答案,但我想在这里填写所有的空白:


有没有办法在MongoDB中原子地更新两个集合?


否。两个集合的原子更新实际上是一个事务。 MongoDB不支持跨集合甚至集合中的事务。



MongoDB提供几个修饰符,它们在单个文档上是原子的。所以你可以一次增加几个不同的变量( $ inc )。虽然在这里有一些限制,你不能在单个属性上执行两个不同的操作。


有条件的一种方式 .mongodb.org / display / DOCS / Atomic + Operations>原子更新。但是,您真正需要的是一个队列和某种形式的两阶段提交,或者您需要触发器。



触发器具有尚未实施,所以它不是你的情况下真的一个选项。


有可能的消息将标记为读取之间的那些操作,然后我会减少未读计数错误。


在这一点上,你有几个不同的策略,的一致性。坦率地说,根据您的说明,您可能需要调查构建一个更新总计的简单队列。


I have a collection of messages:

{
    messageid: ObjectId
    userid: ObjectId
    message: string
    isread: true|false
}

and a collection of message counts per user:

{
    userid: ObjectId
    total: int
    unread: int
}

When I delete a message from "messages" collection, I also need to decrease "total" in "counts" collection, and conditionally (if "messages.isread" == false) decrease "unread" field as well.

For that I need to first retrieve teh message, check its "isread" field, and then update the counts. There is a possibility that the message will be marked as read in between those actions, then I will decrease "unread" counts incorrectly.

Is there a way to conditionally change something in one collection based on results of other collection in one shot?

解决方案

There are lots of answers here, but I want to fill in all of the blanks here:

Is there any way to atomically update two collections in MongoDB?

No. Atomic update of two collections is effectively a transaction. MongoDB does not support transactions across collections or even within a collection.

MongoDB provides several modifiers that are atomic on a single document. So you can increment several different variables at once ($inc). Though there are some limitations here, you cannot perform two different operations on a single property.

Is there a way to conditionally change something in one collection based on results of other collection in one shot?

There are some documents here on atomic updates in general. However, what you really need is a queue and some form of two-phase commit or you need triggers.

Triggers have not yet been implemented, so it's not really an option in your case.

There is a possibility that the message will be marked as read in between those actions, then I will decrease "unread" counts incorrectly.

At this point, you have a couple of different strategies for making this behave with some level of consistency. Frankly, based on your description, you may want to investigate building a simple queue that updates your totals.

这篇关于有没有办法在MongoDB中原子地更新两个集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆