【データベース】ロック(排他制御)
複数ユーザーが同時にDB更新しても矛盾が起きないようにする仕組み
ロックの種類
- 共有ロック(READロック)
- 他ユーザーのSELECTだけ認める
- ユーザーのログイン処理とか
- 占有ロック(WRITEロック)
- 他ユーザーの一切の処理を認めない
- ECサイト等で在庫数で矛盾が起きないようにSELECTも認めたくないとき
ロックの範囲
- テーブルロック
- 行(=レコード)ロック
SELECT FOR UPDATE
- 行単位で共有ロックをかけるSQL文(他ユーザーのSELECTのみ許す)
- 必ずトランザクションを開始すること(開始しないとただのSELECT文になる)
- 他ユーザーが対象の行をSELECT FOR UPDATEしようとすると、待ち状態になる
- 一定時間が過ぎると
Lock wait timeout exceeded;
エラーになる - トランザクションを開始した方を
commit
すると、SELECTできるようになる
- 一定時間が過ぎると
注意点
- トランザクションの中で行うこと
- ユニークに行指定できる条件を使うこと
- 処理が終わったら
COMMIT
orROLLBACK
でトランザクションを終了させてロック解除 begin
したらすぐにSELECT FOT UPDATE
どのロックが良いのか?
- ケースバイケース
- アドバイザリロックが便利
- 楽観的ロックはほぼ見かけない
- SELECT FOR UPDATEは使用注意(デッドロックしないように!)