MySQL处理高并发,防止库存超卖库存出现负数的方法
mysql处理高并发的方式比较多,以下为比较简单的一种(mysql事物控制)
begintranse();
try{
$result = $dbca->query('select amount from s_store where postid = 12345');
if(result->amount > 0){
//quantity为请求减掉的库存数量
$dbca->query('update s_store set amount = amount - quantity where postid = 12345');
}
}catch($e exception){
rollback('');
}
commit();
// 咋一看此方法貌似没有问题,但如果仔细看会发现这个方法是不可取的
// 比如你购买商品的数量是大于1的此时如果库存只剩下1 执行库存就会出现负数的情况
// 就算是商品库存大于1 当有大量的请求挤进事物时会产生一个共享锁,所以在select的时候查询出来的结果都是满足条件的
// 这个时候update更新语句会把并发串行化,也就是给同时到达这里的update语句排个序,
// 一个一个执行,并生成排他锁,在当前这个update语句commit之前,其他用户等待执行,commit后,生成新的版本;这样执行完后,库存肯定为负数了。
// 所有我们需要一个小小的改动:
begintranse();
try{
//quantity为请求减掉的库存数量,先减去库存
$dbca->query('update s_store set amount = amount - quantity where postid = 12345');
$result = $dbca->query('select amount from s_store where postid = 12345');
if(result->amount < 0){
throw new exception('库存不足');
}
}catch($e exception){
rollback(回滚)
}
commit(提交事务)
简化后:
begintranse(开启事务)
try{
//quantity为请求减掉的库存数量
$dbca->query('update s_store set amount = amount - quantity where amount>=quantity and postid = 12345');
}catch($e exception){
rollback();
}
commit();
上一篇: vue中多次调用同一个定义全局变量方法
下一篇: php中的static