17

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(LOCK IN SHARE MODE)とlockForUpdate(FOR UPDATE)の違いを理解できません

ところで、データベースがinnodbであることを確認しました

4

3 に答える 3

20

これは最終的に機能しますが、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;
        }));
    }
于 2016-01-01T13:45:29.313 に答える