手动锁定MongoDB

时间:2015-04-09 06:33:55

标签: mongodb locking atomic consistency

我有这些操作:

  1. 从集合中查找文档。
  2. 根据它的当前值操作doc.prop,其中" prop"是一个字符串。
  3. 将doc更新回集合。
  4. 所以在这种情况下,我必须确保这些操作是原子的,因为更新doc.prop必须基于当前值。

    以下是两种方法: 1.在doc中添加" valueKey"(Number)属性,确保在更新doc时匹配valueKey。更新后增加valueKey。如果valueKey不匹配,请将此更新标记为失败,然后重试。 2.使用" fsyncLock"在操作期间由MongoDB提供锁定整个mongod实例。

    我上面提到的第一种方法很好,但是当同时面对大量的这些操作时,"失败"和"重试"会经常发生。

    第二种方法,我还没试过,我认为是备份数据库,在这种情况下并不好。

    所以我想知道还有其他有效的方法吗?

1 个答案:

答案 0 :(得分:0)

第一种方法称为optimistic lock。乐观锁定假设碰撞概率很低,否则,正如您已经指出的那样,有很多重试。这些重试也可能是破坏性的 - 如果编辑文本,合并编辑可能是有意义的,但对于电话号码几乎没有意义。

锁定整个数据库是悲观(离线)锁的一种极端形式,其中故意减少系统的并发性。但是,这有问题,因为clients don't know what's going on - 他们的编辑只会失败,这是最糟糕的用户体验。

因此,如果客户有可能知道某些东西被锁定,那么悲观锁定才有意义。例如,您需要告知用户无法编辑她想要编辑的项目,因为其他人已经处于该项目的编辑模式。这也有问题,特别是如果另一个用户离开屏幕并阻止所有其他用户。

但是,如果你想要一个悲观的锁,那绝对不应该像全局数据库锁那样实现:只需锁定项本身并在代码中实现锁定的业务逻辑。

士气:这不是技术问题,这是一个逻辑问题。 Google Docs演示了一种允许同时编辑多个用户的方法,但它很难实现,在其他类型的应用程序中使用有限,并且仍被某些用户视为烦人。 Git和喜欢的人展示了另一种方法,其中分支,合并和冲突的逻辑也暴露给用户,但异步(多版本并发控制)。