コードロード

エラー討伐

【データベース】ロック(排他制御)

複数ユーザーが同時にDB更新しても矛盾が起きないようにする仕組み

ロックの種類

  • 共有ロック(READロック)
    • 他ユーザーのSELECTだけ認める
    • ユーザーのログイン処理とか
  • 占有ロック(WRITEロック)
    • 他ユーザーの一切の処理を認めない
    • ECサイト等で在庫数で矛盾が起きないようにSELECTも認めたくないとき

ロックの範囲

  • テーブルロック
  • 行(=レコード)ロック

SELECT FOR UPDATE

  • 行単位で共有ロックをかけるSQL文(他ユーザーのSELECTのみ許す)
  • 必ずトランザクションを開始すること(開始しないとただのSELECT文になる)
  • 他ユーザーが対象の行をSELECT FOR UPDATEしようとすると、待ち状態になる
    • 一定時間が過ぎると Lock wait timeout exceeded; エラーになる
    • トランザクションを開始した方を commit すると、SELECTできるようになる

注意点

  • トランザクションの中で行うこと
  • ユニークに行指定できる条件を使うこと
  • 処理が終わったら COMMIT or ROLLBACKトランザクションを終了させてロック解除
  • begin したらすぐに SELECT FOT UPDATE

どのロックが良いのか?

  • ケースバイケース
  • アドバイザリロックが便利
  • 楽観的ロックはほぼ見かけない
  • SELECT FOR UPDATEは使用注意(デッドロックしないように!)

参考

データベースのロック(排他制御)とは?ロックの種類や仕組みを解説 - YouTube