GORM で行ロックを獲得する方法
PostgreSQL での GORM を使用時の行ロック、select ~ for update 構文について。
公式サイトでは以下のように記載されている。
// Add extra SQL option for selecting SQL
db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)
//// SELECT * FROM users WHERE id = 10 FOR UPDATE;
しかし、PostgreSQL 使用時には ↑ の書き方ではロックは獲得できない。
構文としては以下のようになる。
// Begin Transaction
tx := db.Begin()
// Add extra SQL option for selecting SQL
tx.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)
// update user model in transaction
tx.Model(&user).Update("name", "hello")
// Commit
tx.Commit()
PostgreSQL でテーブルロック、行ロックなどロックを獲得するにはトランザクションブロック内でロックを獲得する必要がある。
そして、行ロック獲得時に排他ロックをかけているデータに変更を行うにはロックを掛けているトランザクションを使用して Update など行う必要がある。
ロックが終了するタイミングとしてはコミット、あるいはロールバックが行われてトランザクションが終了したタイミングとなる。
参考 URL
GORM: http://gorm.io/ja_JP/
PostgresSQL ロック: https://www.postgresqlinternals.org/chapter6/