本文共 685 字,大约阅读时间需要 2 分钟。
在TP下的实验:public function mysql_a()
{
db('goods')->where('id',2)->setInc('num');
$info = db('goods')->where('id',1)->find();
sleep(1);
if( $info['num']>0 ){
db('goods')->where('id',1)->setDec('num');
}
}
模拟并发请求:
执行前:
执行后:
压测结果:
如果当前为抢购或秒杀场景,此时就会出现超卖情况。
解决方案:public function mysql_a()
{
// 启动事务
Db::startTrans();
try {
Db::name('goods')->where('id',2)->setInc('num');
$num = Db::name('goods')->where('id',1)->lock(true)->value('num');
sleep(1);
if( $num>0 ){
Db::name('goods')->where('id',1)->setDec('num');
}
// 提交事务
Db::commit();
} catch (Exception $e) {
// 回滚事务
Db::rollback();
}
}
压测结果:
加上lock(true)的实际就是在查询语句最后加上 for update(必须跟事务同时使用),此时新开窗口再次查询加锁这条数据,你会发现另一个窗口的查询会一直等待,直到第一个窗口的事务提交。
转载地址:https://blog.csdn.net/weixin_34237125/article/details/113889282 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!