समवर्ती समस्याओं के बारे में, आपके पास एक 'आसान' है दूसरी विधि में किसी भी समवर्ती समस्या को रोकने का तरीका, अपने लेन-देन के अंदर लेख लाइन पर एक चयन करें (For update
अब निहित है)। एक ही लेख पर कोई भी समवर्ती प्रविष्टि उसी लॉक को प्राप्त करने में सक्षम नहीं होगी और आपकी प्रतीक्षा करेगी।
नए डिफ़ॉल्ट आइसोलेशन स्तरों के साथ, लेन-देन में क्रमांकन स्तर का उपयोग किए बिना भी आप अपने लेन-देन के अंत तक वोट टेबल पर कोई समवर्ती सम्मिलन नहीं देखेंगे। तो आपका एसयूएम सुसंगत रहना चाहिए या सुसंगत जैसा दिखता है . लेकिन अगर एक समवर्ती लेन-देन उसी लेख पर एक वोट सम्मिलित करता है और आपके सामने प्रतिबद्ध होता है (और यह दूसरा आपका इंसर्ट नहीं देखता है), तो अंतिम लेन-देन काउंटर को अधिलेखित कर देगा और आप 1 वोट खो देंगे। तो पहले एक चयन का उपयोग करके लेख पर एक पंक्ति लॉक करें (और निश्चित रूप से लेन-देन में अपना काम करें)। इसका परीक्षण करना आसान है, MySQL पर 2 इंटरैक्टिव सत्र खोलें और BEGIN के साथ लेनदेन शुरू करें।
यदि आप ट्रिगर का उपयोग करते हैं तो आप डिफ़ॉल्ट रूप से लेन-देन में हैं। लेकिन मुझे लगता है कि आपको समवर्ती ट्रिगर्स (परीक्षण करने में कठिन) के लिए एक अंतर्निहित पंक्ति लॉक बनाने के लिए आलेख तालिका पर चयन भी करना चाहिए।
- ट्रिगर हटाना न भूलें।
- अपडेट ट्रिगर्स को न भूलें।
- यदि आप ट्रिगर्स और स्टेइन कोड का उपयोग नहीं करते हैं, तो सावधान रहें कि वोट पर प्रत्येक क्वेरी डालने/हटाने/अपडेट करने से लेन-देन से पहले संबंधित लेख पर एक पंक्ति लॉक करना चाहिए। किसी एक को भूलना बहुत कठिन नहीं है।
अंतिम बिंदु:लेन-देन शुरू करने से पहले कठिन लेनदेन करें:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
इस तरह आपको लेखों पर पंक्ति ताले की आवश्यकता नहीं है, MySQL यह पता लगाएगा कि उसी पंक्ति पर एक संभावित लेखन होता है और जब तक आप समाप्त नहीं कर लेते तब तक अन्य लेनदेन को अवरुद्ध कर देगा। लेकिन किसी ऐसी चीज़ का उपयोग न करें जिसकी आपने पिछले अनुरोध से गणना की हो . अद्यतन क्वेरी लेखों पर लॉक रिलीज़ की प्रतीक्षा कर रही होगी, जब पहले लेन-देन COMMIT
द्वारा लॉक जारी किया जाता है SUM
. की गणना गिनती के लिए फिर से किया जाना चाहिए। तो अपडेट क्वेरी में SUM
होना चाहिए या जोड़ें।
update articles set nb_votes=(SELECT count(*) from vote) where id=2;
और यहां आप देखेंगे कि MySQL स्मार्ट है, एक गतिरोध का पता लगाया जाता है यदि 2 लेन-देन ऐसा करने का प्रयास कर रहे हैं, जबकि एक समवर्ती समय में सम्मिलित किया गया है। क्रमांकन स्तरों में मुझे इसके साथ गलत मान प्राप्त करने का कोई तरीका नहीं मिला है:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
insert into vote (...
update articles set nb_votes=(
SELECT count(*) from vote where article_id=xx
) where id=XX;
COMMIT;
लेकिन ब्रेकिंग ट्रांजैक्शन को संभालने के लिए तैयार रहें जिसे आपको फिर से करना होगा।