Występuje problem, który moim zdaniem powoduje, że proces ponownego indeksowania ceny produktu powoduje wyjątek impasu w procesie realizacji transakcji.
Złapałem ten wyjątek podczas realizacji transakcji:
Wyjątek konwersji zamówienia: SQLSTATE [40001]: Błąd serializacji: 1213 Podczas próby uzyskania blokady znaleziono zakleszczenie; spróbuj ponownie uruchomić transakcję
Niestety nie mam śledzenia pełnego stosu z powodu miejsca, w którym został przechwycony wyjątek, ale sprawdzając status INNODB udało mi się wyśledzić impas:
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`
Blokowanie tabeli SQL żądającej jest ostatecznie generowane, Mage_CatalogInventory_Model_Stock::registerProductsSale()
gdy próbuje uzyskać bieżącą liczbę zapasów w celu jej zmniejszenia.
W momencie wystąpienia zakleszczenia proces ponownego indeksowania ceny produktu był uruchomiony i zakładam, że miał blokadę odczytu, catalog_product_entity table
która spowodowała zakleszczenie. Jeśli dobrze rozumiem zakleszczenie, każda blokada odczytu spowoduje zakleszczenie, ale ponowne indeksowanie ceny produktu utrzymuje blokadę przez długi czas, ponieważ witryna zawiera ~ 50 000 produktów.
Niestety, w tym momencie w kodzie przepływu transakcji karta kredytowa klienta została obciążona (za pomocą niestandardowego modułu płatności), a utworzenie odpowiedniego obiektu zamówienia nie powiodło się.
Moje pytania to:
- Czy logika niestandardowego modułu płatności jest wadliwa? tj. Czy istnieje akceptowany przepływ zapewniający, że Magento może bezpłatnie przekonwertować ofertę na wyjątek zamówienia przed obciążeniem metodą płatności (kartą kredytową)?
Edycja: Wygląda na to, że logika modułu płatniczego jest rzeczywiście błędna, ponieważ wywołanie $ paymentmethod-> autoryzacja () powinno nastąpić po miejscu, w którym występuje ten impas, a nie wcześniej (zgodnie z odpowiedzią Iwana poniżej). Jednak transakcja będzie nadal blokowana przez impas (choć bez błędnego obciążenia karty kredytowej).
To wywołanie funkcji
$stockInfo = $this->_getResource()->getProductsStock($this, array_keys($qtys), true);
wMage_CatalogInventory_Model_Stock::registerProductsSale()
sprawia, że odczyt zamek, jak niebezpieczne byłoby zrobić to bez blokowania odczytu?Szukając odpowiedzi w Internecie, kilka miejsc zasugerowało, aby nie przeprowadzać pełnego ponownego indeksowania, gdy witryna jest gorąca; nie wydaje się dobrym rozwiązaniem; czy problem indeksowania powodujący zakleszczenia tabeli i rywalizację o blokady jest znanym problemem w Magento, czy istnieją obejścia?
Edycja: Wydaje się, że pozostałe pytanie tutaj to pytanie trzecie; ponowne indeksowanie powodujące zakleszczenia tabeli. Szukasz obejścia tego problemu.
Edycja: Koncepcja, że impasy nie są same w sobie problemami, a raczej reakcja na nie powinna być przedmiotem zainteresowania, ma wiele sensu. Dalsze dochodzenie w celu znalezienia punktu w kodzie w celu uchwycenia wyjątku zakleszczenia i ponownego wysłania żądania. Robienie tego na poziomie adaptera DB Zend Framework to jedno podejście, ale szukam również sposobu na wykonanie tego w kodzie Magento w celu ułatwienia konserwacji.
W tym wątku znajduje się interesująca łatka: http://www.magentocommerce.com/boards/viewthread/31666/P0/, która wydaje się rozwiązywać powiązany warunek impasu (ale nie ten konkretnie).
Edycja: Najwyraźniej impas został rozwiązany do pewnego stopnia w CE 1.8 Alpha. Wciąż szukam obejścia, dopóki ta wersja nie będzie w wersji alfa