假设我有一个包含views_count
,males_views_count
和females_views_count
字段的集合。我希望能够在查看页面时分别$inc
(递增)计数字段。
这个问题是我收到了几个并发连接,并且可能会出现竞争条件。
我一直在阅读Mongodb中的原子操作。他们通常有成功或失败的方法。记录是写入还是不写入。这是否意味着我需要创建逻辑来确定操作是否失败,如果是,请重试它?
回到我的场景。如果我想让每个视图都计数(即使出现竞争条件),该怎么办?我知道Mongodb锁与传统的RDBMS略有不同。通常,我会实现乐观锁定技术。类似于:
begin
# .. do work .. determine if user is a male or a female
stat.save
rescue StaleDocumentError
stat.reload
retry
end
或者原子操作是否意味着防止竞争条件,因为它是执行更新的服务器,它对真相是什么具有权威性?如果是这样,我们是否还需要实现乐观/悲观锁定技术,或者如果我们使用原子操作,Mongodb会为我们处理这个吗?
答案 0 :(得分:2)
如果您使用$inc
等原子操作,则没有竞争条件。如果您有两个来自不同线程的增量,它们将按照服务器接收的顺序应用,并且在应用这两个操作后,文档的最终结果将是相同的。
如果您使用$set
将字段更新为特定值,则“获胜”值将是最后应用的$set
。如果您的应用程序用例可能导致相同字段的更新冲突,那么乐观锁定/版本控制将非常有用。
就异常处理而言,您应该假设任何数据库操作都可能导致服务器异常(网络错误,重复键,...)并在适当时重试。原子更新与非原子更新不需要任何特殊逻辑,除非您选择实现自己的乐观锁定(在这种情况下,您可能会重新获取当前版本的文档并重试操作)。
MongoDB手册涵盖了Isolate Sequence of Operations中的几种不同模式。