इसके बजाय FOR UPDATE
LOCK IN SHARE MODE
. का उपयोग करें . FOR UPDATE
अन्य लेनदेन को भी पंक्ति को पढ़ने से रोकता है। LOCK IN SHARE MODE
पढ़ने की अनुमति देता है, लेकिन अद्यतन करने से रोकता है।
संदर्भ:MySQL मैन्युअल
------ सत्र 1
START TRANSACTION;
SELECT * FROM test WHERE t=1 LOCK IN SHARE MODE;
UPDATE test SET NAME='irfandd' WHERE t=2;
COMMIT;
----- सत्र 2 (जो अब और अवरुद्ध नहीं किया जा रहा है :))
START TRANSACTION;
UPDATE test SET NAME='irfandd' WHERE t=4;
COMMIT;
अपडेट करें:
यह महसूस करते हुए कि तालिका में कोई अनुक्रमणिका नहीं है t
. पर , मेरे पास निम्नलिखित स्पष्टीकरण है:
सबसे पहले, लेन-देन T1 पंक्ति 1 . को लॉक करता है में SELECT * FROM test WHERE t=1 FOR UPDATE
इसके बाद, लेन-देन T2 UPDATE test SET NAME='irfandd' WHERE t=4
. यह पता लगाने के लिए कि कौन सी पंक्ति (पंक्तियाँ) प्रभावित हैं, उसे पंक्ति 1 . सहित सभी पंक्तियों को स्कैन करना होगा . लेकिन वह लॉक है, इसलिए T2 को T1 के समाप्त होने तक प्रतीक्षा करनी चाहिए। यदि कोई अनुक्रमणिका है, तो WHERE t=4
यह तय करने के लिए अनुक्रमणिका का उपयोग कर सकते हैं कि पंक्ति 1 इसमें t=4
. शामिल है या नहीं, इसलिए प्रतीक्षा करने की आवश्यकता नहीं है।
विकल्प 1: test.t
. पर एक इंडेक्स जोड़ें ताकि आपका अपडेट इसका इस्तेमाल कर सके।
विकल्प 2: LOCK IN SHARE MODE
. का उपयोग करें , जो केवल रीड लॉक लगाने के लिए है। दुर्भाग्य से यह विकल्प एक गतिरोध बनाता है। दिलचस्प बात यह है कि T2 लेनदेन निष्पादित होता है (पंक्ति 4 को अपडेट करना), और T1 विफल रहता है (पंक्ति 2 को अपडेट करना)। ऐसा लगता है कि T1 पंक्ति 4 को रीड-लॉक करता है भी, और चूंकि T2 इसे संशोधित करता है, T1 लेनदेन अलगाव स्तर (डिफ़ॉल्ट रूप से दोहराने योग्य पढ़ें
) अंतिम समाधान लेन-देन अलगाव स्तर<के साथ खेलना होगा /ए> , READ UNCOMMITTED
. का उपयोग करके या READ COMMITTED
लेन-देन का स्तर।
सबसे आसान है विकल्प 1 , IMHO, लेकिन यह आपकी संभावनाओं पर निर्भर है।