lockforupdateを正しく使用/テストする方法を理解しようとしていますが、期待どおりに機能しないことがわかりました
これはただのテストです
public function index() {
return dd(\DB::transaction(function() {
if (\Auth::guard('user')->check()) {
$model = \App\Models\User::find(1)->lockForUpdate();
sleep(60);
$model->point = 100000;
$model->save();
} else {
$model = \App\Models\User::find(1);
$model->point = 999;
$model->save();
}
return $model;
}));
}
2つのブラウザーでテストしようとすると、ブラウザー1のユーザーがログインし、ブラウザー2がログインしていません。ブラウザー1が更新を押した後、更新がロックされ、更新の60秒前にスリープします。
60秒以内に、ブラウザー2に移動して更新を押しますが、レコードがロックされていません。phpmyadminを確認すると、レコードが更新されます(ブラウザー1による60秒のロックトリガー内)
しかし、60秒後、レコードはブラウザ1によって再度変更されました(ポイント100000)
だから私はlockforupdateが使用されていると誤解していますか?それとも間違ってテストしますか?
私が期待したのは、最初の60秒間はブラウザ2によって行が変更されるべきではないということです(ファビコンの読み込みまたはエラースローのある空白のページ?)
https://laravel.com/docs/5.2/queries#pessimistic-locking
そして私はいくつかの調査をしましたが、sharedLock(共有モードでロック)とlockForUpdate(更新用)の違いを理解できません
ところで、データベースがinnodbであることを確認しました
これは最終的には機能しますが、sharedLock(LOCK IN SHARE MODE)とlockForUpdate(FOR UPDATE)の違いがまだわかりません
public function index() {
return dd(\DB::transaction(function() {
if (\Auth::guard('user')->check()) {
$model = \App\Models\User::lockForUpdate()->find(1);
sleep(30);
$model->point = 100000;
$model->save();
} else {
$model = \App\Models\User::lockForUpdate()->find(1);
$model->point = $model->point + 1;
$model->save();
}
return $model;
}));
}