製品価格の再インデックス付けプロセスがチェックアウトプロセスでデッドロック例外を引き起こしていると思われる問題が発生しています。
チェックアウトプロセスでこの例外をキャッチしました。
順序変換例外:SQLSTATE [40001]:シリアル化の失敗:1213ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再開してみてください
残念なことに、例外がキャッチされたため、完全なスタックトレースはありませんが、INNODBステータスを確認すると、デッドロックを追跡できました。
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(47447, 56678)) FOR UPDATE
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 329624 n bits 352 index
`PRIMARY` of table `xxxx`.`catalog_product_entity`
テーブルロックを要求するSQLはMage_CatalogInventory_Model_Stock::registerProductsSale()
、デクリメントするために現在のインベントリカウントを取得しようとすると最終的に生成され ます。
デッドロックが発生した時点で、製品価格の再インデックスプロセスが実行されてcatalog_product_entity table
いたため、デッドロックの原因となった読み取りロックがあったと想定しています。デッドロックを正しく理解している場合、読み取りロックはすべてデッドロックを引き起こしますが、サイトには約50,000個の製品があるため、製品価格の再インデックスはかなりの期間ロックを保持します。
残念ながら、チェックアウトコードフローのこの時点までに、顧客のクレジットカードは(カスタム支払いモジュールを介して)請求され、対応する注文オブジェクトの作成は失敗しました。
私の質問は:
- カスタム支払いモジュールのロジックに問題がありますか?すなわち、支払い方法(クレジットカード)への請求をコミットする前に、Magentoが見積を無料で注文例外に変換できるようにするための承認されたフローはありますか?
編集: $ paymentmethod-> authorize()への呼び出しは、このデッドロックが発生する場所の前ではなく、後に発生するため、支払いモジュールのロジックは実際に障害があります(以下のIvanの回答による)。ただし、トランザクションはデッドロックによってブロックされます(ただし、クレジットカードへの誤った請求はありません)。
この関数呼び出し
$stockInfo = $this->_getResource()->getProductsStock($this, array_keys($qtys), true);
はMage_CatalogInventory_Model_Stock::registerProductsSale()
ロック読み取りを行いますが、非ロック読み取りにすることはどれほど危険ですか?Webで回答を検索する際に、サイトがホットな間は完全な再インデックスを実行しないことをいくつかの場所が提案しました。良い解決策とは思えない。テーブルのデッドロックとロックの競合を引き起こすインデックス作成の問題は、Magentoの既知の問題ですが、回避策はありますか?
編集: ここに残っている質問は3番目の質問からのものであるようです。テーブルのデッドロックを引き起こすインデックスの再作成。このための回避策を探しています。
編集:デッドロックは問題ではなく、それ自体が問題であるという概念ですが、むしろデッドロックへの応答が焦点である必要があり、多くの意味があります。さらに調査して、デッドロック例外をキャッチし、要求を再発行するコード内のポイントを見つけます。Zend Framework DBアダプターレベルでこれを行うことは1つのアプローチですが、Magentoコードでこれを行う方法を探しており、保守性が向上しています。
このスレッドには興味深いパッチがあります:http : //www.magentocommerce.com/boards/viewthread/31666/P0/これは、関連するデッドロック状態を解決するようです(ただし、これは特にそうではありません)。
編集:明らかにデッドロックはCE 1.8 Alphaである程度対処されました。このバージョンがアルファ版になるまで回避策を探しています