2012-06-30 13 views
7

मेरे पास एक ऐसी वेबसाइट है जहां उपयोगकर्ता टिकट खरीद सकते हैं, लेकिन टिकट की मात्रा आमतौर पर सीमित होती है और जल्दी जाती है। मैं एक एस्क्रो सिस्टम को कार्यान्वित करने की कोशिश कर रहा हूं जैसे कि उपयोगकर्ता क्लिक कर सकता है कि वे टिकटों की एक्स संख्या चाहते हैं, जिस बिंदु पर मैं उन्हें एस्क्रो राज्य में डाल दूंगा। इससे उन्हें अपनी क्रेडिट कार्ड की जानकारी दर्ज करने और खरीद पूरी करने में कई मिनट मिलते हैं।MySQL परमाणु संचालन और तालिका लॉकिंग

मेरे पास तीन प्रासंगिक टेबल हैं: ईवेंट, टिकट और एस्क्रो। इवेंट टेबल में एक पंक्ति घटना का वर्णन करती है, जिसमें अधिकतम टिकट उपलब्ध हैं।

user_id: उपयोगकर्ता है कि खरीदी टिकट

number_of_tickets: कितने टिकट वे

event_id खरीदा:

टिकट तालिका निम्नलिखित रखती प्रासंगिक घटना

एस्क्रो तालिका निम्न है:

user_id: क्रय टिकट

number_of_tickets की प्रक्रिया में उपयोगकर्ता: कितने टिकट वे चाहते हैं

event_id: प्रासंगिक घटना

वर्तमान में, मैं तीन करना MySQL प्रश्न, अधिकतम टिकटों में से एक, बेचे गए टिकटों की संख्या के लिए एक, और पहले से ही एस्क्रो में टिकटों की संख्या के लिए एक। तब मैं गणना:

$remaining_tickets = $max_tickets - $tickets_sold - $tickets_in_escrow; 
if ($remaining_tickets >= $tickets_desired) 
{ 
    beginEscrow($user_id, $event_id, $tickets_desired); 
} 
else 
{ 
    echo "Error: not enough ticket remain."; 
} 

मेरे समस्या यह है कि यह संभव है एक से अधिक उपयोगकर्ता एक ही समय में इस कोड को क्रियान्वित होने के लिए है। यदि के बाद एक उपयोगकर्ता को beginEscrowपर कॉल करना था, तो दूसरा उपयोगकर्ता पहले से ही एस्क्रो में पहले से ही टिकटों की संख्या पढ़ चुका था, यह संभव है कि मैं शो को ओवरले कर दूंगा।

मैं अपने टेबल के लिए इनो डीबी इंजन का उपयोग कर रहा हूं, और मैंने पढ़ा है कि SELECT .... FOR UPDATE का उपयोग करके एक पंक्ति को कैसे लॉक करना है, लेकिन मैं एक पंक्ति को अपडेट नहीं कर रहा हूं। beginEscrow फ़ंक्शन बस एस्क्रो तालिका में एक नई पंक्ति डालेगा। मैं सही घटना आईडी के साथ सभी पंक्तियों को पढ़ने और उनमें से प्रत्येक में टिकटों की संख्या जोड़कर $tickets_in_escrow की गणना करता हूं।

शायद मैं इसके बारे में सब गलत कर रहा हूं?

क्या मुझे पूरी तालिका को लॉक करने की आवश्यकता है?

टिकट एस्क्रो सिस्टम लिखने वाला पहला व्यक्ति नहीं हो सकता। मैंने इस तरह की चीज पर कुछ ट्यूटोरियल खोजने की कोशिश कर मौत के लिए खुद को गुमराह कर दिया है, लेकिन मारा। कोई भी विचार मददगार होगा।

धन्यवाद!

उत्तर

9

आप अपने डिजाइन पर बहुत करीब हैं, लेकिन वहां नहीं है।

सबसे पहले, आपकी ईवेंट तालिका को आपके ईवेंट के लिए अभी भी उपलब्ध टिकटों की संख्या रखने की आवश्यकता है (जो भी आप चाहते हैं उसके अलावा)।

दूसरा, आपकी एस्क्रो तालिका में एक डेटाटाइम कॉलम होना आवश्यक है जब एस्क्रो समाप्त हो जाता है। जब भी टिकट एस्क्रो में जाते हैं तो आपको उस मूल्य को सेट करने की आवश्यकता होती है।

तीसरा, एस्क्रौ में टिकट लगाने का लेन-देन

  1. को घटना पंक्ति ताला की जरूरत है।
  2. उपलब्ध टिकट कॉलम पढ़ें। (यदि पर्याप्त नहीं है तो निरस्त करें)
  3. एस्क्रो तालिका
  4. में उपलब्ध पंक्ति कॉलम को कम करने के लिए ईवेंट पंक्ति अपडेट करें।
  5. ईवेंट पंक्ति अनलॉक करें।

चौथा, बिक्री को पूरा करने की कार्रवाई को एस्क्रो पंक्ति को हटाने और बेची गई टिकट पंक्ति डालने की आवश्यकता है। यह मुश्किल नहीं है।

पांचवां, आपको एस्क्रो क्लीनअप ऑपरेशन की आवश्यकता है। इसे समाप्त होने वाली सभी एस्क्रो पंक्तियों की तलाश करने की आवश्यकता है (जिनके पास अतीत में समाप्ति तिथि है) और प्रत्येक के लिए:

  1. संबंधित ईवेंट पंक्ति को लॉक करें।
  2. एस्क्रो तालिका
  3. एस्क्रो तालिका पंक्ति को हटाएं से एस्क्रोड टिकटों की संख्या पढ़ें।
  4. उपलब्ध टिकट कॉलम बढ़ाने के लिए ईवेंट पंक्ति अपडेट करें।
  5. ईवेंट पंक्ति अनलॉक करें।

चाल उपलब्ध एक तरीका है कि सही ढंग से इंटरलॉक है में बनाए रखा टिकट की संख्या के लिए है, इसलिए उपयोगकर्ताओं के बीच दौड़ की स्थिति आपके घटना oversell नहीं है।

+0

तो दूसरे शब्दों में, एस्क्रो टेबल की पंक्तियों की तुलना में, एस्क्रो टिकट गिनती की सभी पंक्तियों को एक ही पंक्ति में एक पंक्ति में होना चाहिए। मैं देखता हूं कि यह कैसे समझ में आता है। धन्यवाद। – user1493634

+0

असल में, सभी टिकट गिनती - उपलब्ध, एस्क्रोड, और बेची गई, एक ही पंक्ति में एक पंक्ति के एक कॉलम में होनी चाहिए। वह कॉलम शून्य हिट करता है, बेचने के लिए और सीट नहीं। लेकिन आपके पास विचार है। –

+0

स्टैक ओवरफ्लो पर, यदि कोई उत्तर आपकी सहायता करता है तो आपको हरे रंग के चेकमार्क पर क्लिक करके इसे स्वीकार करना चाहिए। –

संबंधित मुद्दे