9

Magento 1.7.0.2 Community Edition を使用していますが、デッドロックと「ロック待機タイムアウトを超えました」というエラーという大きな問題に遭遇しました。特定のCRONタスクの実行 中に問題が発生する

  • 製品のインポート/更新 (サイズ、色、メーカーも)。約 5000 の製品がありますが、90% のスクリプトで「ロック待機タイムアウトを超えました」エラーまたはデッドロック エラーが発生します。スクリプトは Magento ガイドラインを使用して開発されており、他のプロセスが実行されていない場合は正常に動作します。たとえば、reindex が実行されている場合、確実にエラーが発生します。テーブルロックが原因である継ぎ目
  • Magento は場合によっては読み取りロックを設定します。私はすでにこれに関するいくつかのトピックを読みましたが、唯一の適切な解決策は/lib/Zend/Db/Statement/Pdo.php _execute 関数を変更することです。Magento を最新の安定バージョンにアップグレードすることを楽しみにしているため、コア ファイルを変更する余裕はありません。

だから私の質問 - これを回避する方法はありますか (PHP、MySQL、またはサーバー (nginx を使用) レベルのいずれか)?

4

5 に答える 5

9

一度に 5 つまたは 6 つ以上の製品をインポートしようとしているときに、この問題に遭遇しました。デッドロックの詳細については、こちらを参照してください。

この問題を解決するには、次のように、データベース クエリを可能な限り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;
}

これについてさらにサポートが必要な場合は、お気軽にお知らせください。

于 2012-11-12T20:39:00.000 に答える
4

顧客がカートに何かを追加しようとしたときに、デッドロックが 1 日に数回ポップアップするという同様の問題がありました。私たちのものも、その時点で更新されていたインデックスに関連しているように見えました (ほとんどの場合、カタログ テーブルの再インデックス)。最終的にこの問題を解決した唯一の方法は、非同期再インデックスを実装することでした (拡張機能を購入することになりました)。

于 2013-05-24T15:09:22.683 に答える
3

製品を並行して保存しようとしても、この問題に遭遇しました。

私たちが直面した主な問題は、製品が最初に保存された後、その後の索引付けプロセスが製品保存トランザクションでカバーされないことでした。そのため、デッドロックに遭遇するたびに、それはインデクサーが原因であり、その上、無効な製品 URL を引き起こし、発生するたびにすべてを再インデックス化することを余儀なくされた矛盾したデータベースがありました。

最終的な解決策は、トランザクションにインデクサーを含め、デッドロックに陥ったトランザクションを再試行することでした。ただし、これは理想的な解決策ではありません。むしろ、私たちが思いつく最善の方法であり、99% の確率で機能します。

Magento の問題点は、プログラミングがずさんで、コーディングに対するイベント駆動型のスイス アーミー ナイフ アプローチが、magento の内部メカニズムに多くの深刻な問題をもたらすことです。

次のアプローチは、製品を並行して保存し、magento 保存と同じ結果でデータベースを残すために、ゼロから作成された独自のインターフェイスです。これはもちろん、拡張機能が製品に関連している場合に備えて、拡張機能をこの新しい概念に統合せずに追加することはできないことを意味します。

于 2013-10-09T07:07:57.403 に答える
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();
}
于 2015-12-08T08:51:20.613 に答える