PostgreSQLでは、複数のトランザクションが同じデータを同時に更新しないように排他ロックをかける機能があります。その代表的な方法がFOR UPDATE句です。この記事では、FOR UPDATEを使った排他ロックの仕組みや活用例を詳しく解説します。
正しく排他ロックを理解することで、データの整合性を保ちながら同時更新を制御できます。
FOR UPDATEとは何か
FOR UPDATE句はSELECT文の後に追加することで、読み取った行に排他ロックをかけ、他のトランザクションによる更新や削除を防ぎます。これにより、同じデータに対する同時変更による競合を避けられます。
基本構文は次の通りです: SELECT * FROM table_name WHERE condition FOR UPDATE;
具体的な使用例
例えば、在庫管理アプリで特定の商品在庫を取得し、その後更新する場合。
BEGIN; SELECT stock FROM products WHERE id = 1 FOR UPDATE; UPDATE products SET stock = stock – 1 WHERE id = 1; COMMIT;
この例では、SELECTで取得した行がトランザクション中にロックされるため、他のトランザクションが同じ行を変更することはできません。
FOR UPDATEの応用とオプション
FOR UPDATEには、NOWAITやSKIP LOCKEDといったオプションもあります。NOWAITを使うと、ロックできない場合に即座にエラーを返します。SKIP LOCKEDを使うと、既にロックされている行をスキップして処理可能です。
これにより、キュー処理や分散システムでの競合回避に柔軟に対応できます。
注意点とベストプラクティス
FOR UPDATEを使用する際は、ロックが長時間保持されると他のトランザクションが待機状態になるため、パフォーマンスに注意が必要です。また、トランザクションの開始と終了を明確に管理することが重要です。
必要に応じてインデックスを活用し、ロック対象行を最小化することで、データベース全体の効率を維持できます。
まとめ
PostgreSQLのFOR UPDATEを使うことで、SELECTで取得した行に排他ロックをかけ、他トランザクションからの更新や削除を防ぐことができます。トランザクション管理とオプションの適切な使用により、安全かつ効率的にデータ操作を行えます。
複数ユーザーが同じデータを扱うシステムでは、FOR UPDATEを理解して適切に活用することが、整合性とパフォーマンスの両立に不可欠です。


コメント