https://www.slideshare.net/takukobayashi560/my-sqltake2-2
http://blog.toshimaru.net/rails-4-transaction-isolation/
解決方法
トランザクション分離レベルをREPEATABLE READからREAD COMMITTEDに変更する
プロダクトコードがあらかじめDB上にあって、後からユーザー情報を紐付けるような処理を例にする
ActiveRecord::Base.transaction isolation: :read_committed do # ここにトランザクション分離レベルを書く
failers = 0
begin
license = License.find_or_initialize_by(expired: nil)
touroku(license)
rescue => e
failers += 1
retry if failers < 5
raise e
end
end
原因
MySQLではデフォルトでファジーリードが発生しないようになっている、トランザクション内で同一レコードを2回読み取った時、別の場所で変更されていても、トランザクション内ではレコードが変わらない。