何が起こっているかの基本的な考え方は次のとおりです。
begin transaction
some_data=select something from some_table where some_condition;
if some_data does not exists or some_data is outdated
new_data = insert a_new_entry to some_table
commit transaction
return new_data
else
return some_data
end
複数のプロセスが上記のコードを同時に実行すると (クライアントが同じ要求を同時に多数発行する場合など)、実際には 1 つしか必要ないのに、多数の「new_data」が挿入されます。
これは並行性の非常に典型的なシナリオだと思いますが、それでもそれを回避する適切な方法がわかりません。select_or_insert ジョブを実行するための単一のワーカー プロセスを持つことや、分離レベルを Serializable(unacceptable) に設定することなど、私が考えることができることです。しかし、どちらも私にはまったく満足のいくものではありません。
PS: データベースは mysql、テーブル エンジンは innodb、分離レベルは反復可能読み取りです。