अब तक अच्छा है, यह कम से कम उपयोगकर्ता को कई सत्रों में चेकआउट करने से रोकेगा (कई बार एक ही कार्ड को चेकआउट करने की कोशिश कर रहा है - डबल क्लिक से निपटने के लिए अच्छा है।)
आप कैसे जांचते हैं? एक मानक के साथ SELECT या एक SELECT ... FOR UPDATE . के साथ ? चरण 5 के आधार पर, मुझे लगता है कि आप आइटम पर एक आरक्षित कॉलम या कुछ इसी तरह की जाँच कर रहे हैं।
यहाँ समस्या यह है कि SELECT ... FOR UPDATE चरण 2 में FOR UPDATE लागू नहीं होगा बाकी सब पर ताला। यह केवल उसी पर लागू होता है जो SELECT है एड:cart-item टेबल। नाम के आधार पर, यह प्रत्येक कार्ट/उपयोगकर्ता के लिए एक अलग रिकॉर्ड होने जा रहा है। इसका मतलब है कि अन्य लेन-देन को आगे बढ़ने से नहीं रोका जाएगा।
उपरोक्त का पालन करते हुए, आपके द्वारा प्रदान की गई जानकारी के आधार पर, यदि आप SELECT ... FOR UPDATE का उपयोग नहीं कर रहे हैं, तो आप एक ही आइटम को खरीदने वाले कई लोगों के साथ समाप्त हो सकते हैं। चरण 3 पर।
सुझाया गया समाधान
- लेन-देन शुरू करें
SELECT ... FOR UPDATEcart-itemटेबल.
यह एक डबल क्लिक को चलने से रोक देगा। आप यहां जो चुनते हैं वह किसी प्रकार का "कार्ट ऑर्डर किया गया" कॉलम होना चाहिए। यदि आप ऐसा करते हैं, तो दूसरा लेन-देन यहां रुक जाएगा और पहले के समाप्त होने की प्रतीक्षा करेगा, और फिर उस परिणाम को पढ़ें जो पहले डेटाबेस में सहेजा गया था।
यदि cart-item . है तो चेकआउट प्रक्रिया को यहीं समाप्त करना सुनिश्चित करें तालिका कहती है कि इसे पहले ही ऑर्डर कर दिया गया है।
SELECT ... FOR UPDATEवह तालिका जहां आप रिकॉर्ड करते हैं कि कोई आइटम आरक्षित किया गया है।
यह अन्य कार्ट/उपयोगकर्ताओं को उन वस्तुओं को पढ़ने में सक्षम होने से रोक देगा।
परिणाम के आधार पर, यदि आइटम आरक्षित नहीं हैं, तो जारी रखें:
-
UPDATE ...चरण 3 में तालिका, आइटम को आरक्षित के रूप में चिह्नित करना। कोई अन्यINSERTकरें एस औरUPDATEआपको भी चाहिए। -
भुगतान करो। अगर भुगतान सेवा कहती है कि भुगतान काम नहीं करता है तो रोलबैक जारी करें।
-
सफल होने पर भुगतान रिकॉर्ड करें।
-
लेन-देन करें
सुनिश्चित करें कि आप ऐसा कुछ भी नहीं करते हैं जो चरण 5 और 7 (जैसे ईमेल भेजना) के बीच विफल हो सकता है, अन्यथा लेन-देन के वापस आने की स्थिति में, आप उनके साथ भुगतान किए बिना भुगतान कर सकते हैं।
चरण 3 यह सुनिश्चित करने के संबंध में महत्वपूर्ण कदम है कि दो (या अधिक) लोग एक ही वस्तु को ऑर्डर करने का प्रयास न करें। यदि दो लोग कोशिश करते हैं, तो दूसरा व्यक्ति अपने वेबपेज को "हैंग" कर देगा, जबकि यह पहले को प्रोसेस करता है। फिर जब पहला समाप्त हो जाता है, तो दूसरा "आरक्षित" कॉलम पढ़ेगा, और आप उपयोगकर्ता को एक संदेश वापस कर सकते हैं कि किसी ने उस वस्तु को पहले ही खरीद लिया है।
लेन-देन में भुगतान या नहीं
यह सब्जेक्टिव है। आम तौर पर, आप एक साथ कई लोगों को डेटाबेस से इंटरैक्ट करने से रोकने के लिए, जितनी जल्दी हो सके लेन-देन बंद करना चाहते हैं।
हालाँकि, इस मामले में, आप वास्तव में चाहते हैं कि वे प्रतीक्षा करें। बस कितनी देर की बात है।
यदि आप भुगतान से पहले लेन-देन करना चुनते हैं, तो आपको अपनी प्रगति को किसी मध्यवर्ती तालिका में रिकॉर्ड करना होगा, भुगतान चलाना होगा, और फिर परिणाम रिकॉर्ड करना होगा। ध्यान रखें कि यदि भुगतान विफल हो जाता है, तो आपको अपने द्वारा अपडेट किए गए आइटम आरक्षण रिकॉर्ड को मैन्युअल रूप से पूर्ववत करना होगा।
चुनें ... गैर-मौजूद पंक्तियों पर अपडेट के लिए
चेतावनी का एक शब्द, यदि आपके टेबल डिज़ाइन में उन पंक्तियों को सम्मिलित करना शामिल है जहाँ आपको पहले SELECT ... FOR UPDATE की आवश्यकता है :यदि कोई पंक्ति मौजूद नहीं है, तो उस लेन-देन के कारण अन्य लेन-देन प्रतीक्षा नहीं करेंगे, यदि वे SELECT ... FOR UPDATE वही गैर-मौजूद पंक्ति।
इसलिए, सुनिश्चित करें कि आप हमेशा SELECT ... FOR UPDATE . करके अपने अनुरोधों को क्रमबद्ध करें एक पंक्ति पर जिसे आप जानते हैं पहले मौजूद है। फिर आप SELECT ... FOR UPDATE उस पंक्ति पर जो अभी तक मौजूद हो भी सकती है और नहीं भी। (केवल एक SELECT करने का प्रयास न करें उस पंक्ति पर जो मौजूद हो भी सकती है और नहीं भी, क्योंकि आप लेन-देन शुरू होने के समय पंक्ति की स्थिति पढ़ रहे होंगे, उस समय नहीं जब आप SELECT चलाते हैं . तो, SELECT ... FOR UPDATE गैर-मौजूद पंक्तियों पर अभी भी कुछ ऐसा है जो आपको सबसे अद्यतित जानकारी प्राप्त करने के लिए करने की आवश्यकता है, बस जागरूक रहें कि इससे अन्य लेनदेन प्रतीक्षा नहीं करेंगे।)