钱包余额使用的是记录和,但是现在负数了
\DB::transaction(function () {
//查询用户余额
$all_price = UserSales::query()->where([‘user_id’ => $this->user_id])->sum(‘price’);
if($all_price < $price)throw new \Exception(‘余额不足’)
})
现在有用户的余额是负数了,懵逼,看了下提交时间有3秒的时间差,难道数据写入有延迟?
修改余额的时候 直接用 update money = money - x from table where money > x,不要先查询再操作
如果在获取 $all_price 之后,其他进程有数据插入,那么这时候的 $all_price 还是上一次查询的结果...这种情况下,判断余额的条件其实是不准确的... 然后正常执行后续程序之后(插入数据),再求和的时候,就可能出现负数...
楼主你这个错误是最基础的并发问题,应该对每一个用户在操作余额使用的时候加锁,常用方式使用文件锁或者行锁。
看看是不是存记录的地方逻辑有问题
解决方案是:
1.若不允许负数 字段设为 无符号 2.更新时加上 price >= xx ; 3.若有涉及并发 加锁 或放到队列里去处理