Почему вызов блокировки общего ресурса перед монопольной блокировкой создает мертвую блокировку? - PullRequest
0 голосов
/ 17 октября 2019

Я использую пессимистическую блокировку от Laravel .

Этот код вызывается первым (давайте пометим его как код A):

DB::transaction(function () {
     $account = Balance::sharedLock()->find(1);

     sleep(4);

     $account->amount -= 20;
     $account->save();
});

И через секунду этокод выполняется в другой вкладке (код B):

DB::transaction(function () {
    $account = Balance::lockForUpdate()->find(1);

    sleep(4);

    $account->amount -= 20;
    $account->save();
});

Вторая вкладка умирает и возвращает исключение мертвой блокировки.

Я не понимаю, почему это происходит.

Это то, что я ожидаю:

  1. Код A создает общий замок и спит
  2. Код B хочетисключительная блокировка, но это невозможно из-за общей блокировки. Итак, Код B ожидает.
  3. Код A уменьшает сумму на 20 и снимает общую блокировку
  4. Код B должентеперь получите эксклюзивную блокировку, спите, уменьшите на 20 и снимите блокировку

Почему вместо этого есть исключение тупиковой блокировки?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...