Я использую пессимистическую блокировку от 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();
});
Вторая вкладка умирает и возвращает исключение мертвой блокировки.
Я не понимаю, почему это происходит.
Это то, что я ожидаю:
- Код A создает общий замок и спит
- Код B хочетисключительная блокировка, но это невозможно из-за общей блокировки. Итак, Код B ожидает.
- Код A уменьшает сумму на 20 и снимает общую блокировку
- Код B должентеперь получите эксклюзивную блокировку, спите, уменьшите на 20 и снимите блокировку
Почему вместо этого есть исключение тупиковой блокировки?