Violation de contrainte d'intégrité: 1062 Entrée en double pour la clé 'UNQ_SALES_FLAT_INVOICE_INCREMENT_ID'

13

J'aide un marchand à rechercher la cause première de certaines transactions de paiement qui ont échoué (au cours d'une journée de commande lourde), qui ont échoué avec l'erreur suivante

SQLSTATE [23000]: violation de contrainte d'intégrité: 1062 entrée en double '51986' pour la clé 'UNQ_SALES_FLAT_INVOICE_INCREMENT_ID'

L' UNQ_SALES_FLAT_INVOICE_INCREMENT_IDindex est une clé unique sur la increment_idcolonne du sales_flat_invoicetableau. Quand je regarde dans ce tableau pour le increment_idmentionné dans l'erreur ( 51986), je trouve qu'il y a déjà une facture avec ceincrement_id , et c'est pour une commande passée par un autre client.

Mes 2 questions liées à cela

  • Où dans Magento CE 1.9.0.1 un ID de facture est-il normalement créé?

  • Existe-t-il des problèmes connus dans un stock Magento CE 1.9.0.1 avec des ID de facture en collision pour des commandes quasi simultanées?

Je me rends compte que l'ID d'incrément 51986signifie que le magasin a une sorte d'extension pour changer les ID d'incrément installés, mais je veux m'assurer qu'il n'y a pas de science connue w / r / t à cela avant d'aller trop loin dans cette voie.

Alan Storm
la source
1
Ajout de Mage_Eav_Model_Entity_Type :: fetchNewIncrementId () comme point de débogage.
Alan Storm
1
J'ai déjà vu cela, mais c'était dû à quelqu'un plaçant un save()appel de méthode dans un événement d'observateur spécifique qui pouvait parfois provoquer ce problème - dans les jours précédant la révision du code;)
Erfan
@AlanStorm, juste par curiosité, pourquoi entrer dans l'entité Eav, je pense, Invoice est un modèle plat.
Prateek
Je crois que cela peut également arriver avec Magento stackoverflow.com/questions/25918091/…
Kristof at Fooman
1
Je le sais plus ancien, mais la table eav_entity_store a été copiée pour une raison quelconque. Il s'agit d'une erreur courante, où le dernier identifiant de commande ne correspond pas à la commande passée. Magento utilise donc la table eav_entity_store pour déterminer l'ID à insérer dans la table de commande, et dans ce cas, il existe déjà. Notez également qu'il s'agit d'un problème très courant avec l'extension du numéro de commande FooMan car il peut contourner cette vérification et provoquer ce problème de manière inattendue.
Rob

Réponses:

3

Commande, facture, creditmemo, l'expédition était EAV jusqu'au 1.6 (?)

La facture @Prateek ÉTAIT un modèle EAV et l'incrément_id l'est toujours.

Increment_id création et problème

L'ID d'incrément est créé ici

\Mage_Eav_Model_Entity_Attribute_Backend_Increment which calls
\Mage_Eav_Model_Entity_Abstract::setNewIncrementId which calls
\Mage_Eav_Model_Entity_Type::fetchNewIncrementId

Je suppose que parce que dans la dernière méthode, la transaction est lancée (et la table / la ligne n'est pas verrouillée), une deuxième création d'ordre peut passer et prendre la même nouvellement créée increment_id .

Solution

Je suppose que si vous verrouillez la ligne / table avant de lire, vous pouvez éviter que tout autre processus ne lise la table jusqu'à ce que vous écriviez un nouveau increment_id. Cela pourrait aider: Comment verrouiller une ligne après avoir utilisé load ()?

Mais je crains que le verrouillage de la ligne entraîne une perte de performances.

Fabian Blechschmidt
la source
1
Je viens de voir ce post et @Fabian, c'est bon à savoir. SE devrait également déclencher des notifications lorsque quelqu'un est mentionné dans une réponse.
Prateek