我正在使用Magento 1.7.0.2社区版,我遇到了一个大问题 - 死锁和“锁定等待超时超时”错误。执行特定 CRON 任务时存在问题
所以我的问题 - 有没有办法如何避免这种情况(无论是在PHP,MySQL还是服务器(我们使用nginx)级别)?
答案 0 :(得分:9)
我在试图同时导入超过五六种产品时遇到了这个问题。有关死锁的更多信息here。
要解决这个问题,我必须尽可能将数据库查询放在SERIALIZABLE次交易中,如下所示:
$adapter = Mage::getModel('core/resource')->getConnection('core_write');
// Commit any existing transactions (use with caution!)
if ($adapter->getTransactionLevel > 0) {
$adapter->commit();
}
$adapter->query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
$product->save(); // etc
交易示例:
$adapter = Mage::getModel('core/resource')->getConnection('core_write');
// Commit any existing transactions (use with caution!)
if ($adapter->getTransactionLevel > 0) {
$adapter->commit();
}
$adapter->query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
$adapter->beginTransaction();
try {
$adapter->query(/* SQL goes here */);
$adapter->commit();
} catch (Exception $e) {
// Rollback on fail always
$adapter->rollBack();
throw $e;
}
如果您需要任何进一步的帮助,请随时告诉我。
答案 1 :(得分:4)
我们遇到了类似的问题,当客户试图将某些东西添加到购物车中时,每天会出现几次死锁。我们似乎也与当时刷新的索引有关(很可能是目录表的重新索引)。我们最终解决这个问题的唯一方法是实现异步重新索引(我们最终购买了扩展程序)。
答案 2 :(得分:3)
我们遇到了这个问题,并尝试并行保存产品。
我们遇到的主要问题是,在最初保存产品之后,产品保存事务不包括随后的索引过程。 因此,每当我们遇到死锁时,它都是由索引器引起的,并且最重要的是我们有一个不一致的数据库导致无效的产品网址并迫使我们每次发生时重新索引所有内容。
我们最终得到的解决方案是将索引器包含在事务中并重试最终陷入死锁的事务。 然而,这不是一个理想的解决方案,它是我们能想到的最好的解决方案,它可以在99%的时间内工作。
magento的问题在于编程是slopy,事件驱动的swiss-army-knife编码方法导致了magento内部机制中的许多深层次问题。我们的下一个方法是我们自己的界面,从头开始编写,以并行保存产品,并使数据库具有与magento save相同的结果。这当然意味着我们不能再添加扩展而不将它们整合到这个新概念中,以防它们与产品相关。
答案 3 :(得分:1)
这是一个很棒的开源解决方案 - https://github.com/AOEpeople/Aoe_DbRetry
这个模块非常简单,专注于一项任务。它使用扩展版本替换数据库适配器,如果连接丢失,查询无法获得所需的锁定或发生死锁,则会重试查询。通过异常消息检测这三种情况。底层(父)代码实际上将这些异常中的至少一个包含在另一个异常中,因此我们检查它并在需要时解包该异常。
答案 4 :(得分:0)
在使用CRON脚本导入之前,我将索引模式设置为MANUAL。
$indexCollection = Mage::getSingleton('index/indexer')->getProcessesCollection();
foreach ($indexCollection as $process) {
$process->setMode(Mage_Index_Model_Process::MODE_MANUAL)->save();
//$process->setMode(Mage_Index_Model_Process::MODE_REAL_TIME)->save();
}