ฉันประสบปัญหาที่ฉันเชื่อว่ากระบวนการจัดทำดัชนีราคาสินค้าใหม่ทำให้เกิดข้อยกเว้นเดดล็อกในกระบวนการชำระเงิน
ฉันตรวจพบข้อยกเว้นนี้ในกระบวนการเช็คเอาต์:
ข้อยกเว้นการแปลงคำสั่งซื้อ: 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 รายการ
น่าเสียดายที่ ณ จุดนี้ในขั้นตอนการชำระเงินบัตรเครดิตของลูกค้าถูกเรียกเก็บเงิน (ผ่านโมดูลการชำระเงินที่กำหนดเอง) และการสร้างวัตถุใบสั่งที่สอดคล้องกันนั้นล้มเหลว
คำถามของฉันคือ:
- ตรรกะโมดูลการชำระเงินที่กำหนดเองเป็นความผิดพลาดหรือไม่? ie มีกระแสยอมรับหรือไม่ที่จะทำให้มั่นใจได้ว่าวีโอไอพีสามารถแปลงใบเสนอราคาเป็นข้อยกเว้นการสั่งซื้อได้ฟรีก่อนที่จะทำการเรียกเก็บเงินเป็นวิธีการชำระเงิน (บัตรเครดิต)?
แก้ไข: ดูเหมือนว่าตรรกะโมดูลการชำระเงินเป็นความผิดพลาดอย่างแน่นอนเนื่องจากการเรียกไปยัง $ paymentmethod-> Authorize () ควรเกิดขึ้นหลังจากที่สถานที่ซึ่งการหยุดชะงักนี้เกิดขึ้นไม่ใช่ก่อนหน้า (ตามคำตอบของ Ivan ด้านล่าง) อย่างไรก็ตามการทำธุรกรรมจะยังคงถูกปิดกั้นโดยการหยุดชะงัก (แม้ว่าจะไม่มีการเรียกเก็บเงินจากบัตรเครดิต)
ฟังก์ชั่นนี้เรียกใช้
$stockInfo = $this->_getResource()->getProductsStock($this, array_keys($qtys), true);
ในMage_CatalogInventory_Model_Stock::registerProductsSale()
การอ่านล็อคว่ามันอันตรายแค่ไหนที่จะทำให้มันอ่านไม่ล็อค?ในการค้นหาคำตอบของเว็บไซต์สองแห่งไม่แนะนำให้ใช้การจัดทำดัชนีแบบเต็มใหม่ในขณะที่ไซต์กำลังร้อนแรง ดูเหมือนว่าจะเป็นทางออกที่ดี เป็นปัญหาของการจัดทำดัชนีที่ทำให้เกิดการหยุดชะงักของตารางและล็อคการช่วงชิงปัญหาที่ทราบใน Magento มีวิธีแก้ไขหรือไม่
แก้ไข: ดูเหมือนคำถามที่เหลืออยู่ที่นี่เป็นคำถามจากคำถามที่สาม; การสร้างดัชนีใหม่ทำให้ตารางหยุดชะงัก กำลังมองหาวิธีแก้ปัญหาสำหรับสิ่งนี้
แก้ไข:แนวคิดที่การหยุดชะงักไม่ได้อยู่ในตัวของมันเอง แต่การตอบสนองต่อพวกมันควรจะเป็นจุดสนใจ การตรวจสอบเพิ่มเติมเพื่อหาจุดในรหัสเพื่อตรวจจับข้อยกเว้น deadlock และออกคำร้องขอใหม่ การทำสิ่งนี้ในระดับอแด็ปเตอร์ Zend Framework DB เป็นวิธีหนึ่ง แต่ฉันกำลังมองหาวิธีการทำเช่นนี้ในรหัส Magento เพื่อความสะดวกในการบำรุงรักษา
มีแพทช์ที่น่าสนใจในหัวข้อนี้: http://www.magentocommerce.com/boards/viewthread/31666/P0/ที่ดูเหมือนว่าจะแก้ปัญหาการหยุดชะงักที่เกี่ยวข้อง (แต่ไม่ใช่อันนี้โดยเฉพาะ)
แก้ไข: การหยุดชะงักอย่างเห็นได้ชัดได้รับการแก้ไขในระดับหนึ่งใน CE 1.8 Alpha ยังคงมองหาวิธีแก้ปัญหาจนกว่ารุ่นนี้จะไม่ใช้ Alpha