繁体   English   中英

Laravel中处理并发

[英]Handling concurrency in Laravel

我正在创建一个与 MySQL 库存数据库交互的 API。 我们有 15 个用户可以预订产品,按以下方式更新数据库:

  • 降低产品的on-hand价值并增加产品的reserved价值。

inventory表如下所示:

id        int
sku       varchar
on-hand   int
reserved  int

问题是:如果 2 个用户同时尝试更新该行,如何处理该行的更新?

我考虑的第一个方法是使用Transactions

<?php
    function reserveStock()
    {
        $db->beginTransaction();

        // SELECT on-hand, reserved from inventory

        // Update inventory values

        $db->commit();

        return response()->json([ 'success' => 1, 'data' => $data ])
    }

第二个是使用悲观锁定

<?php
    function reserveStock()
    {

        // SELECT on-hand, reserved from inventory with ->sharedLock()

        // Update inventory values

        return response()->json([ 'success' => 1, 'data' => $data ])
    }

第三个是创建一个值为 cero 的updating字段。 选择要更新的产品时,我会在对该行执行任何操作之前检查updating字段。 我在这里看到的问题是我必须循环updating != 0直到它们可用。 更多选择和更新来自他的方法。

哪种行动方式最好? 可能有比我在这里写的更多的选择。

既不要使用事务,也不要使用悲观主义者锁定。

也不要使用更新。

对于赛车状况,您最好查看数据库,并摆脱更新,而使用插入。 制作数据透视表以适应用户和产品之间的连接。 并且仅使第一个连接记录(其中id较小)成为实际记录。

如果需要更多说明,请参考以下示例

假设有2位用户竞相购买该产品。 他们俩几乎同时在数据透视表中创建记录,但应该有人来做,对吧? 他们俩都进行非常小的事务来持久化数据。 然后-他们俩都读取数据透视表以验证谁成功。 这两个记录的第一条记录都是相同的,不会有任何阻塞使用(显式租用)。 因此,一个客户将获得他的记录并感到高兴,而另一个将要重新申请以获得另一种产品。

问题解决了。

我知道我迟到了,但我可以帮助像我这样遇到类似问题的人。 您可以通过使用作业/队列来解决这个问题。 这样,与用户相关的任何“交易”都不会与另一个用户“同时”运行。 考虑查看这篇关于并发攻击的文章,我相信你会喜欢的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM