Saya mengalami masalah di mana saya percaya proses pengindeksan ulang Harga Produk menyebabkan pengecualian kebuntuan dalam proses checkout.
Saya menangkap pengecualian ini dalam proses checkout:
Pengecualian konversi pesanan: SQLSTATE [40001]: Kegagalan serialisasi: 1213 Deadlock ditemukan saat mencoba mendapatkan kunci; coba mulai kembali transaksi
Sayangnya saya tidak memiliki jejak tumpukan penuh karena di mana pengecualian ditangkap, tetapi memeriksa status INNODB saya dapat melacak kebuntuan:
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`
Kunci tabel permintaan SQL pada akhirnya dihasilkan dari Mage_CatalogInventory_Model_Stock::registerProductsSale()
ketika mencoba untuk mendapatkan jumlah persediaan saat ini untuk menurunkannya.
Pada saat kebuntuan terjadi, proses indeks ulang Harga Produk sedang berjalan dan saya berasumsi itu memiliki kunci baca catalog_product_entity table
yang menyebabkan kebuntuan. Jika saya memahami kebuntuan dengan benar setiap kunci baca akan menyebabkan kebuntuan, tetapi indeks harga produk menahan kunci untuk waktu yang adil karena situs memiliki ~ 50.000 produk.
Sayangnya, pada titik ini dalam alur kode checkout, kartu kredit pelanggan telah ditagih (melalui modul pembayaran khusus), dan pembuatan objek pesanan yang sesuai gagal.
Pertanyaan saya adalah:
- Apakah logika modul pembayaran khusus salah? yaitu apakah ada aliran yang diterima untuk memastikan bahwa Magento dapat mengubah penawaran menjadi pengecualian pesanan gratis sebelum melakukan tagihan ke metode pembayaran (kartu kredit)?
Sunting: Tampaknya logika modul pembayaran memang salah karena panggilan ke $ paymentmethod-> otorize () harus terjadi setelah tempat kebuntuan ini terjadi, bukan sebelumnya (sesuai jawaban Ivan di bawah). Namun, transaksi masih akan diblokir oleh jalan buntu (meskipun tanpa biaya sesat ke kartu kredit).
Ini panggilan fungsi
$stockInfo = $this->_getResource()->getProductsStock($this, array_keys($qtys), true);
dalamMage_CatalogInventory_Model_Stock::registerProductsSale()
merek itu penguncian membaca, betapa berbahayanya itu akan membuatnya non-penguncian membaca?Dalam mencari jawaban di web, beberapa tempat menyarankan tidak menjalankan pengindeksan ulang penuh saat situs sedang panas; sepertinya bukan solusi yang bagus; Apakah masalah pengindeksan menyebabkan kebuntuan tabel dan pertikaian kunci masalah yang dikenal di Magento, apakah ada solusi?
Sunting: Tampaknya pertanyaan yang tersisa di sini adalah pertanyaan dari pertanyaan ketiga; pengindeksan ulang menyebabkan kebuntuan tabel. Mencari solusi untuk ini.
Sunting: Konsep bahwa kebuntuan tidak ada dalam dan tentang masalah mereka sendiri, melainkan tanggapan terhadap mereka harus menjadi fokus, masuk akal. Investigasi lebih lanjut untuk menemukan titik dalam kode untuk menangkap pengecualian kebuntuan dan menerbitkan kembali permintaan. Melakukan hal ini pada tingkat adaptor DB Zend Framework adalah satu pendekatan, tetapi saya juga mencari cara untuk melakukan ini dalam kode Magento untuk memudahkan pemeliharaan.
Ada tambalan yang menarik di utas ini: http://www.magentocommerce.com/boards/viewthread/31666/P0/ yang tampaknya mengatasi kondisi kebuntuan terkait (tapi bukan yang ini secara khusus).
Sunting: Rupanya kebuntuan telah diatasi pada gelar di CE 1.8 Alpha. Masih mencari solusi hingga versi ini keluar dari Alpha
Jawaban:
Ada kemungkinan yang cukup besar bahwa metode pembayaran Anda memproses pembayaran secara salah.
Proses Penyimpanan Pesanan Magento cukup sederhana:
checkout_type_onepage_save_order
dansales_model_service_quote_submit_before
Mage_CatalogInventory_Model_Stock::registerProductsSale()
dipanggil pada pengamat acara ini$order->place()
metode yang memproses pembayaran dengan menelepon$paymentMethod->authorize()
,$paymentMethod->capture()
atau$paymentMethod->initialize()
bergantung pada logikanya.sales_flat_order_*
.Jadi seperti yang Anda lihat, tidak mungkin, metode pembayaran mengenakan biaya sebelum inventaris mengunci dan membaca harga produk atau info produk.
Ini hanya mungkin dalam kasus jika metode pembayaran dilaksanakan sedemikian rupa, sehingga melakukan pemuatan produk dengan harga, setelah panggilan API untuk operasi pengisian dilakukan.
Semoga ini bisa membantu Anda dalam men-debug masalah Anda.
Adapun pengindeksan ulang, itu harus aman, jika Anda tidak memiliki masalah ini dengan metode pembayaran. Sejak operasi baca yang bergantung pada kunci dilakukan sebelum uang dikenakan biaya.
sumber
registerProductsSale()
(memahami bahwa dengan perbaikan ke modul pembayaran khusus akan menghilangkan masalah meminta kartu pelanggan dibebankan).Karena ini adalah ekstensi khusus, kami dapat menemukan solusi khusus (baca: retas) untuk mencoba ulang penyimpanan tanpa mengedit file inti.
Saya telah menyelesaikan semua masalah jalan buntu saya dengan dua metode berikut yang ditambahkan ke kelas pembantu. Alih-alih menelepon
$product->save()
saya sekarang memanggilMage::helper('mymodule')->saferSave($product)
:Ini menyelesaikan dua hal yang berbeda - ini mengantri coba lagi ketika jalan buntu ditemukan, dan menetapkan batas waktu yang meningkat secara eksponensial untuk coba lagi itu. Ini juga menetapkan tingkat isolasi transaksi. Ada banyak informasi tentang SO dan DBA.SE untuk informasi lebih lanjut tentang tingkat isolasi transaksi MySQL.
FWIW, saya tidak pernah menemui jalan buntu sejak itu.
sumber
$tries
ke fungsi inisleep($this->getDelay());
Di forum Magento mereka berbicara tentang mengedit file perpustakaan Zend: lib / Zend / Db / Statement / Pdo.php
Fungsi _execute asli:
Setelah modifikasi:
Seperti yang Anda lihat, satu-satunya hal yang telah diubah adalah $ mencoba telah dipindahkan di luar loop.
Seperti biasa disarankan untuk mencoba ini pada lingkungan pengembangan / pengujian dan tidak langsung menerapkan perbaikan ini pada lingkungan produksi.
sumber
Saya memiliki masalah yang sama pada situs Magento 1.11 dan saya memiliki tiket terbuka dengan Magento sejak 11/12/2012. Mereka mengkonfirmasi itu adalah masalah dan seharusnya membuat tambalan.
Pertanyaan saya adalah mengapa harga harus diindeks ulang saat ini? Saya pikir ini tidak diperlukan:
sumber
Kami memiliki masalah kebuntuan yang serupa ketika panggilan tertentu dilakukan selama indeks ulang. Bagi kami, itu memanifestasikan dirinya sebagian besar ketika pelanggan akan menambahkan sesuatu ke troli. Meskipun mungkin tidak memperbaiki masalah mendasar yang sebenarnya, menerapkan pengindeksan ulang asinkron telah sepenuhnya menghentikan semua panggilan deadlock yang sebelumnya kita lihat. Harus berfungsi sebagai penghenti sementara sampai masalah mendasar diperbaiki dan didorong ke edisi EE / CE (kami akhirnya membeli ekstensi untuk melakukannya).
sumber
Saya sarankan Anda menginstal Philwinkle DeadlockRetry. Ini berfungsi untuk basis data kami.
Saya juga menyarankan melihat program luar Anda yang mengenai api web Anda. Kami punya satu yang memperbarui QTY untuk produk dan itu menyebabkan banyak kebuntuan. Kami menulis ulang itu dan langsung ke database.
sumber
Saya menemui masalah kebuntuan tahun lalu berkali-kali saya mengatasinya hanya dengan meningkatkan memori untuk server kami karena proses pengindeksan memakan semua sumber daya.
Anda juga harus menggunakan kami async reindex solusi yang saya gunakan miravist
Untuk sistem yang lebih stabil, Anda harus memikirkan memisahkan backend Anda dari frontend sehingga mereka tidak saling memakan RAM.
Bagi pengalaman saya, itu bukan masalah kode sumber.
sumber