排他制御とは
複数人の同時アクセスすることによスデータの不整合が発生しないように制御を行うことを意味します。
排他制御には主に2種類があります。
-
楽観ロック
- 更新対象のデータが取得された時点から更新がないことを確認し、その後対象データを更新することでデータの整合性を保証します。
-
悲観ロック
- 更新対象のデータが取得された時点から明示的にロックを行うい、その後更新対象のデータを更新することででデータの整合性を保証します。
- 明示的にロックを行うことにより、他のトランザクション処理による対象更新データを防ぎます。
SELECT ~ FOR UPDATE (NOWAIT) - 行ロックの取得
通常、SELECT分で選択した行には自動的に共有ロックがかかります。しかし、SELECT文の末尾に「FOR UPDATE」を追加することで、排他ロックがかかり、他のトランザクションから該当行のデータを更新するができなくなります。
SQLでの排他制御実装例
SELECT ~ FOR UPDATEの実装例
かけたロックは、コミットまたはロールバック処理によってトランザクションが終了すると解除されます。
BEGIN;
-- データを明示的にロックする
SELECT * FROM USER WHERE NAME = 'A' FOR UPDATE;
-- 処理1
SELECT ~;
-- 処理2
SELECT ~;
-- ロックが解除される
COMMIT;
LOCK TABLE - 表ロックの取得
ある特定の表全体をロックするには、LOCK TABLEを使用します。
LOCK TABLE テーブル IN MODE モード名 (NOWAIT)の実装例
※モード名はEXCLUSIVEで排他ロック、SHAREで共有ロックとなります。
取得された表ロックは、行ロック同様にトランザクションの終了とともに解除されます。
BEGIN;
-- 表を明示的にロックする
LOCK TABLE USER IN EXCLUSIVE MODE;
-- 処理1
SELECT ~;
-- 処理2
SELECT ~;
-- ロックが解除される
COMMIT;