findAndModify
在 mongodb 中很棒,但是我很难知道我修改了哪个嵌入式文档。
这是一个Post
embeds_many的示例Comments
。(我使用的是 Mongoid ORM,但这个问题对于任何 MongoDB 设置都是通用的)。
begin
p = Post.asc(id).where(comments: { '$elemMatch' => {reserved: false} }).find_and_modify({'$set' => {'comments.$.reserved' => true}}, {new: true}
# now i need to find which comment I just reserved
c = p.comments.select{|c| c.reserved }.first
...
ensure
c.update_attribute :reserved, false
end
好的,这种工作,但如果我有多个进程同时运行它,我select
可以选择另一个进程保留的注释(竞争条件)。
这是我目前最接近的(按进程 ID 保留):
begin
p = Post.asc(id).where(comments: { '$elemMatch' => {reserved: nil} }).find_and_modify({'$set' => {'comments.$.reserved' => Process.pid}}, {new: true}
# now i need to find which comment I just reserved
c = p.comments.select{|c| c.reserved == Process.pid }.first
...
ensure
c.update_attribute :reserved, nil
end
这似乎有效。这是最好的方法还是有更好的模式?