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