Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB';s更新原子性是否同时适用于查询和修改?_Mongodb - Fatal编程技术网

MongoDB';s更新原子性是否同时适用于查询和修改?

MongoDB';s更新原子性是否同时适用于查询和修改?,mongodb,Mongodb,MongoDB支持原子更新。也就是说,我可以确保在更新文档时,没有其他更新会覆盖我以前的更改。我的问题与查询和更新语句的组合有关,下面的示例最好地说明了这一点 db.foo.update( { state : 1, players: { $size: 2 } } , { $push: { players : { new player document } } }, false , true ); 在上面的例子中,我只想把一个新玩家推到一个玩家集合中,如果玩家的数量等于2。在上面的查询和更新

MongoDB支持原子更新。也就是说,我可以确保在更新文档时,没有其他更新会覆盖我以前的更改。我的问题与查询和更新语句的组合有关,下面的示例最好地说明了这一点

db.foo.update(
{ state : 1, players: { $size: 2 } } , 
{ $push: { players : { new player document } } }, 
false , true );
在上面的例子中,我只想把一个新玩家推到一个玩家集合中,如果玩家的数量等于2。在上面的查询和更新语句中,两次同时更新是否都会将播放机推送到同一个文档上,因为在读取文档时,播放机的$size是2?即原子性是否跨越update语句的查询和更新部分

编辑更深入的事件顺序:

考虑同时触发两次相同的更新(U1和U2)。以下事件序列是否可能

  • U1发现文档#1与更新的查询部分匹配 声明
  • U2发现文档#1与 更新语句
  • U1在文档#1中推送一个新玩家
  • U2在文档#1中推出了一个新播放器

  • 最终结果是文档#1比预期多了一名玩家,因为U1和U2都认为文档#1只包含两名玩家。

    更新:我对自己的知识再也不确定了。。。看见请不要接受这个答案(或我下面的评论),因为它可能是不正确的。希望得到纠正


    您对atomic的解释不正确(我可以肯定,当文档更新时,其他更新不会覆盖我以前的更改)。其他更新可以(也将)覆盖您的更改。但它们不会以干扰查询完整性的方式进行操作

    重要的是要知道MongoDB更新是可用的。因此,当文档与您的查询匹配时,它将被“锁定”并准备进行更新。请注意,您的更新(
    $push
    )在锁定的同一文档中工作。更新完成后,将释放锁

    我不确定我是否理解“原子性是否跨越update语句的查询和update部分”,但是:原子性意味着其他查询不能干扰我们的查询。我们的查询可以更改自己“锁定”的数据


    免责声明:我不了解MongoDB用于确保原子性的内部机制,因此从技术角度来看(特别是在锁定方面)可能缺少此描述,但它在概念上是有效的。从外部的角度来看,这就是它的工作原理。

    根据你写下的事件顺序,你确实可以让一个玩家玩得太多。更新的“查找”和“更新”的工作原理非常类似于自己对迭代的每个文档进行“查找”和“更新”。您可能想看看“$atomic”操作符:

    我在mongodb用户组上问了这个问题

    根据Marc(在10gen工作)的回答,我所描述的情况是不可能发生的

    你所描述的情况是不可能的;没有危险 修改同一文档的两个更新


    谢谢你的回复。我用一系列事件更新了我的问题,我希望这些事件能澄清一些事情。我现在意识到我要问的不是原子性,而是文档级别的事务(锁)。是的,这确实澄清了问题。你没什么好担心的。在查找和更新(第2步和第4步)之间,没有任何东西可以改变文档,否则操作将不是原子操作。如果它不是这样工作的,那么它就是一个bug,应该这样报告。注意OP只发布了2个更新(U1和U2),这些步骤只是为了说明可能的冲突。