LoginSignup
15
12

More than 3 years have passed since last update.

LaravelでMySQLのテーブルロックを実行する

Last updated at Posted at 2019-11-01

実装例

占有ロック

 DB::unprepared('LOCK TABLES lock_target_table WRITE');

共有ロック

 DB::unprepared('LOCK TABLES lock_target_table READ');

Eloquentのクエリビルダを使う方法は見つけられなかったので、生クエリを実行している

ダメな例

HogeHogeModel::lockForUpdate()->get();

全レコードに対してlockForUpdate()しても、テーブルロックの挙動にならなかった。
(別のトランザクションから、まだ存在しないレコードに対して占有ロック(ギャップロック )をかけることができてしまい、その後デッドロックになるリスクがある)

検証

全行ロックだと存在しない行のロックがブロックされない例

T1 T2 コメント
BEGIN;
BEGIN;
SELECT * FROM locks FOR UPDATE; 行全部ロック
SELECT * FROM locks WHERE name="not_exist_record" FOR UPDATE; 存在しない行のロックが取れてしまう
>Empty set

テーブルロックで存在しない行のロックがうまくブロックされる例

T1 T2 コメント
BEGIN;
BEGIN;
LOCK TABLES locks WRITE; テーブルロック
SELECT * FROM locks WHERE name="not_exist_record" FOR UPDATE; 存在しない行のロック
... T1のテーブルロックが終わるまで待つ
COMMIT;
>Empty set T1のテーブルロックが終わったので実行される

Versions

  • Laravel 5.8
  • MySQL 5.7
15
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
12