2012-12-18 14 views
5

मुझे पता है कि इससे पहले पूछा गया है, लेकिन मैं अभी भी उलझन में हूं और यदि संभव हो तो प्रोग्रामिंग में जाने से पहले किसी भी समस्या से बचना चाहूंगा।माईस्क्ल रेस स्थितियों से ठीक से कैसे बचें

मैं किसी भी समय कम से कम 100 उपयोगकर्ताओं के साथ एक आंतरिक वेबसाइट रखने की योजना बना रहा हूं। उपयोगकर्ता एक आइटम पोस्ट करेंगे (0 के साथ डीबी में डाले गए हैं) और वह आइटम एक php साइट (डीबी क्वेरी) के माध्यम से दिखाया जाएगा। उपयोगकर्ताओं को तब एक बटन दबाए जाने और उस आइटम को उनके रूप में लॉक करने का विकल्प मिलता है (उस आइटम का मान उनके आईडी के रूप में असाइन करें)

मैं कैसे सुनिश्चित करूं कि 2 या अधिक उपयोगकर्ता एक ही समय में एक ही आइटम को पुनर्प्राप्त नहीं करते हैं । मैं प्रोग्रामिंग में जानता हूं जैसे सी ++ मैं सिर्फ सादा ol mutex लॉक का उपयोग करता हूं। क्या उनका MySQL में समतुल्य है जहां यह केवल एक आइटम प्रविष्टि को लॉक करेगा? मैंने LOCK_TABLES और GET_LOCK और कई अन्य लोगों के संदर्भ देखे हैं, इसलिए मैं अभी भी सबसे अच्छा क्या होगा इस पर बहुत उलझन में हूं।

कई लोगों के लिए एक बटन दबाकर दौड़ने की संभावना है और यदि एकाधिक लोगों को पुष्टि मिलती है तो यह विनाशकारी होगा।

मुझे पता है कि यह दौड़ की स्थिति का एक प्रमुख उदाहरण है, लेकिन MySQL मेरे लिए विदेशी क्षेत्र है।

मैं इसे अद्यतन करने से पहले आइटम के मूल्य से पूछताछ करता हूं और सुनिश्चित करता हूं कि यह लिखा नहीं गया है, लेकिन यह सुनिश्चित करने का सबसे अच्छा तरीका क्या है कि इस दौड़ की स्थिति से बचा जा सके।

अग्रिम धन्यवाद।

उत्तर

2

इसे प्राप्त करने के लिए, आपको किसी भी तरह रिकॉर्ड को लॉक करने की आवश्यकता होगी। जब कोई बटन एक प्रश्न पर अमल धक्का इस जैसी एक स्तंभ LockedBy 0.

को दोषी जोड़ें:

अद्यतन तालिका सेट LockedBy = कहां LockedBy = 0 और आईडी =;

अपडेट के बाद प्रभावित पंक्तियों को सत्यापित करें (php mysql_affected_rows में)। यदि मान 0 है तो इसका अर्थ यह है कि क्वेरी ने कुछ भी अपडेट नहीं किया क्योंकि लॉकबी कॉलम 0 नहीं है और इस प्रकार किसी और द्वारा लॉक किया गया है।

आशा इस

+0

एक नया नया कॉलम क्यों बनाएं? क्या आप मौजूदा कॉलम पर इस रणनीति का उपयोग नहीं कर सकते? –

2

में मदद करता है आप एक पंक्ति पोस्ट करते हैं, तो फिर 0.

शून्य करने के लिए स्तंभ, नहीं सेट एक उपयोगकर्ता पंक्ति इसे अपने स्वयं के बनाने के लिए अद्यतन करता है जब, इसे अद्यतन इस प्रकार है:

UPDATE MyTable SET ownership = COALESCE(ownership, $my_user_id) WHERE id = ... 

COALESCE() अपना पहला गैर-शून्य तर्क देता है। तो यदि आप और मैं एक साथ अद्यतन कर रहे हैं, तो प्रतिबद्ध करने वाला पहला व्यक्ति मूल्य निर्धारित करने के लिए मिलता है। दूसरा उस मूल्य को ओवरराइड नहीं करेगा।

0

आप लेन-देन

BEGING TRANSACTION; 
SELECT ownership FROM ....; 
UPDATE table .....; // set the ownership if the table not owned yet 
COMMIT; 

विचार कर सकते हैं और यह भी आप लेन-देन के बीच सभी प्रश्नों रोलबैक कर सकते हैं अगर आप एक त्रुटि पकड़ा!

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