发现问题
今天压测的时候,发现在并发下,发现数据出现下面的情况:
- 数据库里有一个count字段,执行10次代码,本应该-10,结果测了几次却发现,结果总是在-7上下浮动,少减
- 记录count字段变动记录,没有问题,记录了10条-1记录
然后仔细想了下,应该是代码写的有问题。
假如我们的代码是这样的
$row = Model->find($id);
$count = $row->count - 1;
$row->save();
商品余量为10,此时假如两个事务并发执行:
- 第一个事务先获取到count为10,执行到2,3行之间时,count此时为9
- 此时由于第一个事务还未commit,第二个事务开始获取到商品余量仍为10,计算完count也等于9,由于此时需要等待第一个事务的X锁,排队等待第一个事务执行完毕。
- 第一个任务save之后commit,此时数据库中的count为9
- 第二个事务开始执行,直接从内存中获取count为9,执行commit,此时数据库中的count为9
结果:商品余量比实际多1(如果是+1则比实际少1)
正确代码
Model->where('id', $id)->increment('count', 1);