问题
I'm developing a little shopping website for entertainment purpose but I'm intending to apply the same code to a possible real shop website in the future. So I have these "slots" that are meant to be bought, like a reservation slot for saving seats with numbers. So people will buy the slots and save the seats, but I'm facing a race condition problem, even though I'm using lockForUpdate method, I can buy more slots than I have balance for. My piece of code for when the user clicks "buy":
foreach ($tSlots as $mSlot) {
DB::beginTransaction();
$slot = Slots::where('id', $mSlot)->lockForUpdate()->first();
$wallet = $user::getWallet();
$wallet->lockForUpdate();
if (($slot->user_id === null) && ($wallet->balance >= $slot->price)) {
$wallet->balance -= $slot->price;
$slot->user_id = $user->id;
if ($wallet->update() && $slot->update()) {
$counter++;
DB::commit();
} else {
DB::rollBack();
}
} else {
DB::rollBack();
}
}
I'm keeping track of the slots count as I will display how many slots the users has successfully bought on the view after redirection. If i intercept the request and edit it to make, let's say, 4 requests, each buying 5 different slots, I can manage to buy more than I have balance for, and my balance turns negative. Where am I messing it up?
来源:https://stackoverflow.com/questions/52806969/laravel-pessimistic-lock-not-working-like-supposed-to