欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL处理高并发,防止库存超卖库存出现负数的方法

程序员文章站 2022-03-09 21:53:57
mysql处理高并发的方式比较多,以下为比较简单的一种(mysql事物控制) begintranse(); try{ $result = $dbca->query('select am...

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();