इस तरह का एक बयान MyISAM या InnoDB के साथ एक लेन-देन के साथ या autocommit = ON के साथ समान कार्य करता है। यह क्वेरी करने के लिए पर्याप्त ब्लॉक करता है, जिससे अन्य कनेक्शन अवरुद्ध हो जाता है। समाप्त होने पर, दूसरा कनेक्शन आगे बढ़ता है। सभी मामलों में, स्तंभ जल्द ही 11 से कम हो जाता है।
एक तीसरा उपयोगकर्ता 0 या 4 या 7 या 11. द्वारा घटाया गया मान देख सकता है, "बहुत सटीक समय" वास्तव में संभव नहीं है, क्योंकि प्रत्येक कथन के निष्पादन में कुछ बिंदु पर, एक एकल-थ्रेडेड लॉक की जाँच की जाती है / जो भी हो । यही कारण है कि वे, है जाएगा धारावाहिक जा, बस इतनी जल्दी है कि आप इसे नहीं देख सकता।
InnoDB केवल पंक्तियों को लॉक करता है, तालिकाओं को नहीं। (ठीक है, डीडीएल स्टेटमेंट बोल्डर लॉक करता है।)
क्या अधिक दिलचस्प हो जाता है एक लेनदेन जो दो चीजों को संशोधित करता है, या जो ध्यान देने योग्य समय लेता है:
इरादा मामला: एकल आइटम लेकिन समय लग रहा है:
BEGIN;
SELECT something;
think about it for a while
UPDATE that something;
COMMIT;
इस प्रकार चयन की आवश्यकता है:
SELECT something FOR UPDATE;
यह अन्य कनेक्शन को बताता है "मैं पंक्ति को अद्यतन करने का इरादा रखता हूं; कृपया मुझे गड़बड़ न करें"। (मैं इस उदाहरण को सामने लाता हूं, क्योंकि बहुत सारे न्यूबीज इस सूक्ष्मता को याद करते हैं।)
डेडलॉक मामला: 2 चीजों के साथ खिलवाड़:
BEGIN; -- in one connection
UPDATE thing_1;
UPDATE thing_2;
COMMIT;
BEGIN; -- in another connection, at the "exact same time"
UPDATE thing_2;
UPDATE thing_1;
COMMIT;
यह एक गतिरोध का क्लासिक उदाहरण है - प्रत्येक चीज एक चीज को पकड़ती है और फिर दूसरी चीज के लिए पहुंचती है। स्पष्ट रूप से इसे काम करने के लिए नहीं बनाया जा सकता है। एक लेन-देन मारा जाता है; दूसरा पूरा हुआ। इसलिए, आपको त्रुटियों की जांच करनी चाहिए , ताकि आप इसे खोज सकें।
एक गतिरोध की सामान्य प्रतिक्रिया पूरे विफल लेनदेन को फिर से खेलना है। तब तक, दूसरा कनेक्शन हस्तक्षेप नहीं करेगा, और यह परेशानी के बिना आगे बढ़ना चाहिए। (ठीक है, फिर भी एक और कनेक्शन एक और गतिरोध पैदा कर सकता है।)
देरी का मामला: यदि दो कनेक्शन एक ही क्रम में कई चीजों को पकड़ते हैं , तो दूसरे को खत्म होने तक देरी हो सकती है। इसे "हमेशा के लिए इंतजार" से रखने के लिए, एक डिफ़ॉल्ट 50-सेकंड है innodb_lock_wait_timeout
। आपकी जोड़ी सरल UPDATEs
वास्तव में इस मामले का एक उदाहरण है। एक तो तुरंत खत्म हो जाएगा; पहले खत्म होने तक दूसरा रुका हुआ है।
ध्यान दें कि आपके द्वारा स्पर्श की जाने वाली चीजों को लगातार आदेश देकर एक डेडलॉक को (कुछ मामलों में) कैसे एक देरी में बदल दिया जा सकता है।
autocommit = 1: इस सेटिंग के साथ और बिना कॉल किए BEGIN
, प्रत्येक कथन प्रभावी रूप से है:
BEGIN;
your statement
COMMIT;
autocommit = 0: यह होने की प्रतीक्षा में परेशानी है। जब आप एक लेखन क्वेरी करते हैं, तो एक BEGIN
संक्षेप में उत्पन्न होता है। हालाँकि, अंततः जारी करना आपकी ज़िम्मेदारी है COMMIT
। यदि आप ऐसा करने में विफल रहते हैं, तो आपको आश्चर्य होगा कि आपका सिस्टम क्यों लटका हुआ है। (एक और आम नौसिखिया बग।) मेरी सलाह: "कभी उपयोग न करें =0
"।