作为magento专业服务和模块开发人员,我们需要实施Magento订单处理工作流程,其中订单信息从2个独立的并发流程(第三方支付处理通知处理程序和客户到订单分配处理程序)加载,更新和存储。当前的实施工作正常,但该过程容易受到竞争条件问题的影响。
流程A: load()ᴬ - > updateFields1() - >保存()ᴬ
流程B: load()ᴮ - > updateFields2() - >保存()ᴮ
如果在load()after之后但在save()之前调用load()ᴮ,则其中一个进程会覆盖并发进程设置的值。
如果方法updateField1()和updateField2()中更新的字段完全不同,Magento框架是否有可能或某些常规做法来处理竞争条件?
答案 0 :(得分:1)
基本上有两种方法可以避免这种竞争条件。他们都有权衡。
选项A:进行两次单独的UPDATE
查询以更新这些字段,并让数据库服务器为您处理锁定。 Zend的DB Framework已经有了内置的方法来进行这些类型的更新。这里有两个示例函数可以帮助您入门:
function paymentProcessingUpdate($incrementId, $paymentId) {
$db = Mage::getSingleton('core/resource')->getConnection('core_write');
$table = 'sales_flat_order';
$data = array('payment_id' => $paymentId);
$where = $db->quoteInto('increment_id = ?', $incrementId);
$db->update($table, $data, $where);
}
function assignCustomerToOrder($incrementId, $customerId) {
$db = Mage::getSingleton('core/resource')->getConnection('core_write');
$table = 'sales_flat_order';
$data = array('customer_id' => $customerId);
$where = $db->quoteInto('increment_id = ?', $incrementId);
$db->update($table, $data, $where);
}
这种方法的缺点:
sales_flat_order_grid
表中使用,则您也必须更新该表。这是Magento的模型通常会为您做的事情。您可以在单个JOIN
查询中添加UPDATE
来处理此问题。sales_order_save_commit_after
和sales_order_save_after
等观察者不会被触发。优点:
选项B:您可以使用像Mage_Index_Model_Lock
这样的锁定机制,这是Magento在刷新索引时所做的工作。
工作原理:我们假设我们正在处理订单号100002185
。在此示例中,过程A和B可以互换。
automation_order_id_100002185
是否存在锁定。automation_order_id_100002185
设置锁定并开始执行其工作。automation_order_id_100002185
的锁定。这种方法的缺点: