面试的时候遇到的问题,关于PHP并发
大概就是 mysql的一张表存放着某个用户的余额,下面我写伪代码了。
$sql=select * from user wherer 余额 > 10 and id=1;
//如果有余额进行逻辑处理最后在减去扣款。
if($sql){
echo '请求它接口';
$sql=update user set 余额=余额-10;//关键就在这里了,如果减完了就相当于没余额了,但是由于并发,第二个人查询的时候是有的,他也进了这个条件。怎么避免这种情况
}else{
echo '余额不足';
}
globecg
9 years, 6 months ago
Answers
唉,题主你被坑了,这哪里是PHP问题,这明显是数据库问题。
正确的做法是,用存储过程 + 事务 + 锁。
而且一点都不简单,使用存储过程,你需要依次判断:
---->账号是否存在
---->余额够不够
---->数据修改后还要验证是否成功、是否修改正确(某些数据库有bug会导致没修改,或改错。因此自己要先用sql计算一次修改结果用于验证)
反对几种答案:
1.使用乐观锁。这要对表进行改动,增加last_version字段,明显不科学。
2.记录余额、或者在update时先where amount > 10,这也不科学,如果之前该用户的账号被删除了呢?
3.使用队列。以后系统的瓶颈集中在这里,看看老板会不会打死你。
じ☆veD壞づ
answered 9 years, 6 months ago
2种解决办法:”for update“的悲观锁,或者使用”版本号“的乐观锁, http://segmentfault.com/q/1010000002905539
永遠D誓い
answered 9 years, 6 months ago