Nic*_*ick 6 mysql locking magento
问题的高级摘要:在下订单时导致库存表锁定问题导致订单因超时而失败.
通过结帐流程,我看到正在执行以下查询:(我添加的评论)
-- 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)
Run Code Online (Sandbox Code Playgroud)
我对语句FOR UPDATE修饰符的理解SELECT是,在SELECT提交事务之前,将在表中返回的所有行都将被锁定(读取和写入?).
根据我对MySQL的理解,cataloginventory_stock_item查询具有qty列的计算值(即该值未在PHP中计算并传递到查询中),新列值基于执行查询时的现有列值)意味着它不会受到竞争条件的影响.
我的问题是:
catalog_product_entity才能更新股票?cataloginventory_stock_item如果cataloginventory_stock_item UPDATE是原子的?1)是的,您关于FOR UPDATE的假设是正确的,cataloginventory_stock_item和catalog_product_entity中选择的行将被锁定以进行读取和写入。也就是说,针对这些行的其他查询将被阻止。
2)我不知道,实际上似乎并没有。也许这是为了防止用户手动更新库存状态或类似状态时出现竞争情况,但是我仍然看不到为什么无法将其删除。另一种可能性是原始作者打算为每种产品支持多个库存项目,并认为“父母”应该被锁定。
3)因为PHP代码在发布更新之前使用加载的值检查项目是否“可销售”。如果没有锁定,则两个进程可以加载相同的值,然后竞争更新该值。因此,即使它是原子的,但是如果在加载数据时出现竞争条件,查询也不会正确失败。
| 归档时间: |
|
| 查看次数: |
1686 次 |
| 最近记录: |