问题描述
一般电子商务网站都会遇到如团购、秒杀、特价之类的活动,而这样的活动有一个共同的特点就是访问量激增、上千甚至上万人抢购一个商品。
然而,作为活动商品,库存肯定是很有限的,如何控制库存不让出现超卖,以防止造成不必要的损失,是众多电子商务网站程序员头疼的问题,这同时也是最基本的问题。
条件
总库存:4个商品
请求人:a、1个商品 b、2个商品 c、3个商品
错误示例
$pdo->beginTransaction();
try{
$result = $pdo->query('select amount from s_store where postID = 12345');
if($result->amount > 0){
// quantity 为请求减掉的库存数量
$pdo->query('update s_store set amount = amount - quantity where postID = 12345');
}
// 没有错误则提交事务
$pdo->commit();
}catch($e \PDOException){
// 遇到错误则回滚事务
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
}
使用 SELECT ... FOR UPDATE
$pdo->beginTransaction();
try{
// 使用 SELECT ... FOR UPDATE 将此行数据锁住,在提交事务或者回滚事务时自动解开。
$result = $pdo->query('select amount from s_store where postID = 12345 for update');
if($result->amount < 0){
// 抛出异常
throw new \PDOException('库存不足');
}
// quantity 为请求减掉的库存数量
$pdo->query('update s_store set amount = amount - quantity where postID = 12345');
// 没有错误则提交事务
$pdo->commit();
}catch($e \PDOException){
// 遇到错误则回滚事务
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
}
其他方法
$pdo->beginTransaction();
try{
// quantity 为请求减掉的库存数量
$pdo->query('update s_store set amount = amount - quantity where postID = 12345');
$result = $pdo->query('select amount from s_store where postID = 12345');
if($result->amount < 0){
// 抛出异常
throw new \PDOException('库存不足');
}
// 没有错误则提交事务
$pdo->commit();
}catch($e \PDOException){
// 遇到错误则回滚事务
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
}