mysql - 在 Magento 库存数量更新期间使用 "FOR UPDATE"

标签 mysql magento locking

问题的高级摘要:在下订单时获取有关锁定库存表的问题,导致订单因超时而失败。

通过结帐流程,我看到正在执行以下查询:(我添加的评论)

-- Lock stock and product tables
SELECT `si`.*, `p`.`type_id` FROM `cataloginventory_stock_item` AS `si`
INNER JOIN `catalog_product_entity` AS `p` ON p.entity_id=si.product_id
WHERE (stock_id=1) AND (product_id IN(28775, 28777)) FOR UPDATE

-- Perform the actual stock update
UPDATE `cataloginventory_stock_item`
SET `qty` = 
    CASE product_id
        WHEN 28775 THEN qty-2
        WHEN 28777 THEN qty-1
    ELSE
        qty
    END
WHERE (product_id IN (28775, 28777)) AND (stock_id = 1)

我对 SELECT 语句的 FOR UPDATE 修饰符的理解是,SELECT 中返回的表中的所有行都将被锁定(读和写?)直到事务被提交。

根据我对 MySQL 的理解,cataloginventory_stock_item 查询具有 qty 列的计算值(即该值未在 PHP 中计算并传递到查询时,新的列值基于执行查询时的现有列值)意味着它不会受到竞争条件的影响。

我的问题是:

  • 我的假设是否正确?
  • 为什么 Magento 需要锁定 catalog_product_entity 才能更新库存?
  • 如果 cataloginventory_stock_item UPDATE 是原子的,为什么 Magento 需要锁定 cataloginventory_stock_item

最佳答案

1) 是的,您关于 FOR UPDATE 的假设是正确的,在 cataloginventory_stock_item 和 catalog_product_entity 中选择的行将被锁定以进行读写。也就是说,对这些行的其他查询将被阻止。

2) 我不知道,事实上它似乎没有..也许这是为了防止用户手动更新库存状态或类似情况时出现竞争条件,但我仍然不明白为什么它不能'不会被删除。另一种可能是原作者打算支持每个产品的多个库存项目,并认为“父级”应该被锁定。

3) 因为 PHP 代码在发布更新之前使用加载的值检查项目是否“可销售”。如果没有锁定,两个进程可能会加载相同的值,然后争先恐后地更新该值。因此,即使它是原子的,如果在加载数据时存在竞争条件,查询也不会正常失败。

关于mysql - 在 Magento 库存数量更新期间使用 "FOR UPDATE",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21092325/

相关文章:

mysql - 仅当另一行中存在值时才选择一行

android - 将 android 与 MS SQL SERVER 2008 连接

php - 内联翻译在 magento 中不起作用

php - Magento 2 Collection Date 按一小时过滤掉

java - 克服Java中的使用文件问题

locking - DynamoDB 默认有锁定吗?

linux - 是否有 "lock files"的标准 Linux 库?

mysql - Vagrant Chef Recipe 校验和计算

mysql - 如何从特殊表中选择所有记录 order by desc?

apache - 访问 Magento 安装时出现 302 响应