Je rencontre un problème pour lequel je pense que le processus de réindexation du prix du produit est à l'origine d'une exception d'interblocage dans le processus de paiement.
J'ai attrapé cette exception dans le processus de commande:
Exception de conversion de commande: SQLSTATE [40001]: Échec de la sérialisation: 1213 Impasse trouvée lors de la tentative d'obtention du verrouillage; essayez de redémarrer la transaction
Malheureusement, je n'ai pas de trace de pile complète car l'exception a été interceptée, mais en vérifiant l'état INNODB, j'ai pu localiser l'impasse:
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`
Le verrou de table demandant SQL est finalement généré à partir du Mage_CatalogInventory_Model_Stock::registerProductsSale()
moment où il tente d'obtenir le nombre d'inventaire actuel afin de le décrémenter.
Au moment où le blocage s'est produit, le processus de réindexation du prix du produit était en cours d'exécution et je suppose qu'il existait un verrou de lecture sur le catalog_product_entity table
qui a provoqué le blocage. Si je comprends correctement le blocage, tout verrou de lecture entraîne un blocage, mais le réindexage du prix du produit le verrouille pendant un temps raisonnable, car le site contient environ 50 000 produits.
Malheureusement, à ce stade du flux de code de paiement, la carte de crédit du client a été débitée (via un module de paiement personnalisé) et la création de l'objet de commande correspondant a échoué.
Mes questions sont:
- La logique du module de paiement personnalisé est-elle défectueuse? Par exemple, existe-t-il un flux accepté permettant à Magento de convertir le devis en une exception de commande sans frais préalable avant de valider le paiement par le moyen de paiement (carte de crédit)?
Edit: Il semble que la logique du module de paiement soit effectivement défectueuse, car l'appel à $ paymentmethod-> authorize () devrait avoir lieu après le lieu où cette impasse s'est produite, pas avant (comme l'indique la réponse d'Ivan ci-dessous). Cependant, la transaction sera toujours bloquée par l’impasse (même sans les frais erronés sur la carte de crédit).
Cet appel de fonction
$stockInfo = $this->_getResource()->getProductsStock($this, array_keys($qtys), true);
enMage_CatalogInventory_Model_Stock::registerProductsSale()
fait une lecture verrouillée, quel danger y aurait-il à en faire une lecture non verrouillable?En recherchant une réponse sur le Web, plusieurs endroits ont suggéré de ne pas exécuter une réindexation complète tant que le site est à chaud; semble à peine être une bonne solution; La question de l'indexation provoquant des blocages de table et des conflits de verrous est-elle un problème connu dans Magento? Existe-t-il des solutions de contournement?
Edit: Il semble que la question restante ici est celle de la troisième question; réindexation provoquant des blocages de table. Vous cherchez des solutions de contournement pour cela.
Edit: Le concept selon lequel les blocages ne sont pas des problèmes en soi, mais plutôt que la réponse à ces problèmes devrait être au centre des débats, a beaucoup de sens. Enquêtant plus avant pour trouver un point dans le code pour attraper l'exception d'interblocage et réémettre la demande. Faire cela au niveau de l’adaptateur de base de données Zend Framework est une approche, mais je cherche aussi un moyen de le faire dans le code Magento pour faciliter la maintenabilité.
Il y a un correctif intéressant dans ce fil de discussion: http://www.magentocommerce.com/boards/viewthread/31666/P0/ qui semble résoudre une situation de blocage similaire (mais pas celle-ci en particulier).
Edit: Apparemment, l’impasse a été corrigée dans CE 1.8 Alpha. Je cherche toujours une solution de contournement jusqu'à ce que cette version soit sortie de Alpha