Mysqli / PHP防止某些脏读

时间:2018-06-27 01:30:00

标签: php mysqli

目前,我遇到了一个问题,正在为这个问题打断头(尽管我可能会过分思考)。

当前,我在SQL DB中有一个表,其中包含一些产品和库存量。人们可以访问产品页面,或对其进行订购(如果您是管理员,则可以对其进行更新)。但是现在,我对比赛条件感到敬佩。

订购过程如下:

1):会话开始事务。

2)。它将获得当前可用的单位数量。

3)它检查订购的金额是否可用,并减去该金额。

4)它将使用新的“总计”值更新产品表。这是非常短的代码(不使用准备好的语句等)。

BEGIN;
SELECT amount FROM products WHERE id=100;
$available=$result->fetch_array(MYSQLI_NUM)[0];
if($order<=$available){
    $available-=$order;
    UDPATE products SET amount=$available WHERE id=100;
}
//error checking and then ROLLBACK or COMMIT

我现在的问题是: 我该怎么做以防止在步骤2中读取脏数据,从而在步骤4中写回错误的值?

示例:如果一个人订购了10件产品A,而在第3步时,第二个人也订购了5件产品A。因此,在第2步中,它仍将获得“旧”值并与,从而在第4步中恢复了错误的数字。

我知道我可以使用“ SELECT .... FOR UPDATE”这将在行上放置排它锁,但是这也阻止了普通用户(仅在产品页面上)检查可用性以防止立即加载,而我宁愿让他们快速加载页面,也不愿在第二个准确的广告资源上加载页面。因此,基本上,我希望读锁定仅适用于将在同一笔交易中更新值的客户。

是我想要的,还是我需要处理得到的? 预先感谢!

1 个答案:

答案 0 :(得分:0)

有两种方法可以解决该问题:

  1. 只要扣除后的余额低于0,您都可以在MySQL中使用一个函数来更新库存并显示错误“对不起,您的产品刚刚缺货!”。

OR(首选方式)

  1. 您可以在MySQL中使用locking。在这种情况下,它应该是写锁。写锁应禁用其他读取请求(第二人称),直到释放该锁(第一人称)。

希望对您有所帮助!