SELECT FOR UPDATEの動作
· 9分の読み時間
PostgreSQLでは、FOR UPDATEロックはトランザクション内でSELECTクエリを実行する際にテーブルの行を明示的にロックするために使用されます。このロックモードは、選択された行がトランザクションが完了するまで変更されないようにし、他のトランザクションがこれらの行を変更したり、競合するロックをかけたりするのを防ぐために使用されます。
例えば、特定の顧客がチケット予約プロセスを進めている間に他の顧客がデータを変更するのを防ぐために使用されることがあります。
この記事で検討するケースは少し特殊です:
- ロックされた読み取りとロックされていない読み取りが混在する場合、
select for update
はどのように動作するのか? - 最初にロックが使用された場合、他のトランザクションが読み取ることは可能か?
- 読み取り方法が混在してもデータの一貫した読み取りが保証されるか?
PostgreSQLでは、select for update
句はトランザクション分離レベルによって異なる動作をします。したがって、各分離レベルでの動作を確認する必要があります。
以下のデータが存在する場合にデータが変更されるシナリオを仮定します。
id | name |
---|---|
1 | null |
Read Committed
- PostgreSQLのデフォルトの分離レベル。
- トランザクションAが
select for update
を使用して行をロックしても、トランザクションBはデータを読み取ることができます。- ロックなしでの読み取り。
- トランザクションAがコミットするまで、トランザクションBはデータを変更できません。
- トランザクションBがトランザクションAのコミットを待っている場合、トランザクションAがコミットするとすぐにトランザクションBは続行できます。
- 一貫した読み取りは保証されません。
- 更新の損失が発生する可能性があります。