您的位置:首页 > 数据库

关系型数据库如何处理“库存”问题

2015-10-26 09:45 120 查看
在商城中,有一件商品有100件库存,那么用户每购买一件,库存要做减一。 刚开始我想到这样进行处理:

$model = new Model();

//读取商品的库存
$quantity = $model->where(" id = 1 ")->count();

//库存减一
$quantity--;

$result = mysql_query("UPDATE goods SET quantity = $quantity WHERE id = 1 ");

这样的方式,在不考虑并发的情况下是没问题的,但如果有多个用户同时操作,情况就不一样了。

假设两个用户同时购买,A用户读取库存为10,B用户读取库存也是10,A购买完成后,将库存减一,改为9, 而此时,B也将库存减一,改为9。实际卖出了两件,但库存没有正确减少,就会造成“超卖”。

A、B用户的购买流程是交叉执行的。

问题的关键在于上面的代码使用了两条SQL语句,所以造成了不同用户的请求可能交叉执行。 如果能将操作合并到一条SQL语句中,就可以避免这个问题。

请看修改后的代码:

$model = new Model();

$result = mysql_query("UPDATE goods SET quantity = quantity - 1 WHERE id = 1 ");

由于关系型数据库都是存储在文件中,对同一条记录的修改不能同时进行。这意味着即使A、B用户同时购买,修改库存时也是按先后顺序来的,因此库存可以正确的减少。

还有一个问题,如果库存已经为0了,上面的代码就有问题了,因为没有检查库存。

有两种方法解决该问题:

1、将quantity字段设为unsigned,当库存为0时,因为字段不能为负数,将会返回false。

2、修改SQL语句和实现代码:

$model = new Model();

//读取商品的库存
$quantity = $model->where(" id = 1 ")->count();

//库存减一
$quantity--;

$result = mysql_query("UPDATE goods SET quantity = quantity - 1 WHERE id = 1 WHERE quantity > 0 ");
$num = mysql_affected_rows();

if($num == 1){
//成功
}
如果库存为0了,受影响的行将为0,意味着购买失败。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php 数据库