Open1
Posgresqlのrepeatable readでのlost update対策について
Designing Data Intensive Application を読んでいて、MySQL以外の主要なDBはrepeatable read設定だとlost updateを防ぐという記述があって、初見だった。
気になるので普段の開発環境で再現できるか見てみたい。
-
https://www.interdb.jp/pg/pgsql05.html
- 5.8. Preventing Lost Updates に仕様が書かれている
再現
Rails
-
account.balanceに対して2つのトランザクションからアクセス
- tranA:
- read target record
- sleep
- update balance +100
- tranB:
- read target record
- update balance +100
tranA側で、
ERROR:couldn't serialize access due to concurrent update
が発生する? - tranA:
Railsで再現
-
ActiveRecord::Base.transaction(isolation: :repeatable_read)
- isolation modeを設定したトランザクション
ActiveRecord::SerializationFailure
retryは https://github.com/nfedyashev/retryable を使うと行けそう
Prisma
- transaction単位でのisolation modeはサポートしてなさそう
- globalのtransaction isolationの設定
ALTER DATABASE history_db SET DEFAULT_TRANSACTION_ISOLATION TO 'repeatable read';
- Long-running transactionのinterfaceがない
- https://zenn.dev/kanasugi/articles/4dbca26e1c4753
- 2.30にupdateしたけど、変わらず。一旦離脱