findAndModify
很棒,但我知道修改了哪个嵌入式文档时遇到了一些麻烦。
以下是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
这似乎有效。这是最好的方法吗?还是有更好的模式?
答案 0 :(得分:0)
能够通过生成SecureRandom.hex
并使用find_and_modify
在嵌入文档上设置此项来解决此问题。然后,您可以循环浏览嵌入的文档,看看哪个具有匹配的十六进制文件,以查看您正在使用的文档。