Laravel 悲观锁 并发减库存,出现负数的问题。
try{
DB::beginTransaction();
$res = DB::transaction(
function (){
$user = User::lockForUpdate() ->first();
if($user->count < 5){
return "库存不足以您的订单";
}
User::where("id",1)
-> decrement("count",5);
});
DB::commit();
}
catch(\Exception $ex) {
DB::rollBack();
throw $ex;
}
第一种情况:Python爬虫请求(使用grequest并发请求)并发测试,一次发送6个请求访问同一个接口:
第二种情况:手动测试同时刷新两个窗口,添加休眠:
$user = User::lockForUpdate() ->first();
sleep(5);
第一个页面加载完成5秒后,第二个页面加载完成。说明进行了阻塞。锁起作用了。
但是请求非常频繁的情况下(第一种情况下)为什么不起作用了?
第二种情况发生了阻塞,没有出现count字段出现负数的情况,是不是因为不同窗口的问题。第一种情况相当于,刷新同一个窗口。
第二种情况开3个窗口 ,依次执行,每次相隔5秒。应该是不能同窗口的问题,多个窗口相当于多个用户一起发送请求,并且进行阻塞说明锁起到了作用。
不使用DB::transaction,也可以进行阻塞
不同的方法(代码一样),但是没有进行阻塞。出现库存为负数的情况。是怎么回事??
推荐文章: