いくつかの行を選択して以前の値に基づいて更新する必要があるテーブルがあるか、存在しない場合は作成し、複数のHTTP要求が行われた場合は安全にする必要があります。一度に同じ行/レコードに関する。Rails SQlite3 ActiveRecord選択してから更新する
トランザクションとActiveRecord.lockを使ってみましたが、複数のリクエストがあるたびに「ActiveRecord :: StatementInvalid(SQLite3 :: BusyException:データベースがロックされています)」という結果になりました。 select文で、アクティブなレコードが(利用可能な場合例えば、行など、ロック)最も効率的な方法でそうするDBで利用可能な機能を使用している。現在のRuby 2.3とRailsの5を使用して
MyModel.transaction
record = MyModel.lock.find_by(name: update_name) #name is a unique index in the SQL table
if record
# The actual manipulation is more complex than something I want to do directly in a SQL statement
record.update!(value: record.value + add_value)
else
record.create(name: update_name, value: add_value)
end
end
。 1
私はカラムがDB内の一意のインデックスだと言っていますので、私ができる制約の例外を手動で処理する必要があるのであれば、それを破ることはできません。しかし、セレクトとアップデートの間の競争は効果的に私のデータを破壊するでしょう(最後の更新は勝ちですが、それが保存された値は間違っています)。そしてユニークなインデックス違反はありませんので、レスキューするための例外/警告はありません。 –