Mongoid の find_or_create_by メソッドを使用する Web アプリがあります。
poll = Poll.find_or_create_by(fields)
実稼働に入る前に、障害シナリオを実行しようとしていますが、複数のユーザーがこの方法を使用してこのリソースにアクセスしようとする可能性があることに気付きました。同じオブジェクトの複数のインスタンスを作成できる可能性はありますか? それを防ぐにはどうすればよいですか?
Mongoid の find_or_create_by メソッドを使用する Web アプリがあります。
poll = Poll.find_or_create_by(fields)
実稼働に入る前に、障害シナリオを実行しようとしていますが、複数のユーザーがこの方法を使用してこのリソースにアクセスしようとする可能性があることに気付きました。同じオブジェクトの複数のインスタンスを作成できる可能性はありますか? それを防ぐにはどうすればよいですか?
免責事項: 私は Mongoid と Rails を初めて使用するので、完全に間違っている可能性があります。
modifiable.rbとmany.rbを見ると、どのリソースもロックしていないようです。
それは単に「where().first」クエリを実行し、それが何も返さない場合は「作成」クエリを実行するように私には見えます:
def find_or(method, attrs = {}, &block)
where(attrs).first || send(method, attrs, &block)
end
find_or_create_by の場合、「send」は「create_document」を呼び出します。
def create_document(method, attrs = nil, &block)
klass.__send__(method,
selector.reduce(attrs || {}) do |hash, (key, value)|
unless key.to_s =~ /\$/ || value.is_a?(Hash)
hash[key] = value
end
hash
end, &block)
end
結論:これは便利な方法のように見えますが、「スレッドセーフ」であるとは思わないでください。この方法に関するドキュメントがもっとあればいいのにと思います。