我在MongoDB文档中嵌入了子文档数组,多个用户可以尝试将子文档添加到该数组中。我使用update($ push)查询将文档添加到数组中,但是如果多个用户尝试从UI添加条目,如何确保第二个$ push不会由于先锁定而失败?我将只有几个用户在同一文档中添加条目,因此不必担心存在100个用户的情况。在WiredTiger中更新的默认等待时间是多少,因此第二次推送不会立即中止并且最多可能需要1秒钟,但是$ push应该成功完成?
我尝试在MongoDB和WiredTiger文档中找到默认的等待时间,我可以找到事务的默认等待时间,但可以更新查询。
答案 0 :(得分:1)
在内部,WiredTiger使用乐观锁定方法。这意味着当两个线程试图更新同一文档时,其中一个将成功,而另一个将退出。这将表现为“写冲突”(请参见metrics.operation.writeConflicts)。
将透明地重试此冲突,因此从客户的角度来看,写入将比平时花费更长的时间。
退避算法将在遇到更多冲突时等待更长时间,从1毫秒开始,每次等待上限为100毫秒。因此,它遇到的冲突越多,每次重试最终将等待100毫秒。
说过,从多个来源更新单个文档的设计将来会因以下两个原因而难以扩展:
对于#2,在病理情况下,写操作可能在冲突之后遇到冲突,在两次等待之间等待100 ms。等待次数没有上限,因此可能等待几分钟。这表明工作负载在单个文档中处于瓶颈,并且该应用程序本质上在单线程模型上运行。
通常,解决方案不是创建人为瓶颈,而是将工作分散到许多不同的文档中,也许是在单独的集合中。这样,可以保持并发性。