लॉकिंग टेबल अन्य DB उपयोगकर्ताओं को आपके द्वारा लॉक की गई पंक्तियों / तालिकाओं को प्रभावित करने से रोकता है। लेकिन अपने आप में और आपके लॉकेट यह सुनिश्चित नहीं करेंगे कि आपका तर्क सुसंगत स्थिति में है।
एक बैंकिंग प्रणाली के बारे में सोचो। जब आप ऑनलाइन बिल का भुगतान करते हैं, तो लेनदेन से कम से कम दो खाते प्रभावित होते हैं: आपका खाता, जिसमें से पैसा लिया जाता है। और रिसीवर का खाता, जिसमें धन स्थानांतरित किया जाता है। और बैंक का खाता, जिसमें वे खुशी से लेन-देन पर लगाए गए सभी सेवा शुल्क जमा करेंगे। यह देखते हुए (जैसा कि हर कोई इन दिनों जानता है) कि बैंक असाधारण रूप से मूर्ख हैं, मान लें कि उनकी प्रणाली इस तरह काम करती है:
$balance = "GET BALANCE FROM your ACCOUNT";
if ($balance < $amount_being_paid) {
charge_huge_overdraft_fees();
}
$balance = $balance - $amount_being paid;
UPDATE your ACCOUNT SET BALANCE = $balance;
$balance = "GET BALANCE FROM receiver ACCOUNT"
charge_insane_transaction_fee();
$balance = $balance + $amount_being_paid
UPDATE receiver ACCOUNT SET BALANCE = $balance
अब, बिना किसी ताले और लेन-देन के साथ, यह प्रणाली विभिन्न दौड़ की स्थिति के लिए असुरक्षित है, जिसमें से सबसे बड़ा भुगतान आपके खाते में किया जा रहा है या समानांतर में रिसीवर का खाता है। जबकि आपके कोड ने आपके शेष राशि को पुनः प्राप्त कर लिया है और विशाल_ओवरड्राफ्ट_फिसेस () और व्हाट्सएप कर रहा है, यह पूरी तरह से संभव है कि कुछ अन्य भुगतान समान प्रकार के कोड को समानांतर में चला रहे हों। वे आपका शेष राशि प्राप्त करेंगे (कहते हैं, $ 100), उनका लेनदेन करें (आपके द्वारा भुगतान किए जा रहे $ 20 को निकाल लें, और $ 30 वे आपके साथ खराब कर रहे हैं), और अब दोनों कोड पथ में दो अलग-अलग शेष राशि हैं: $ 80 और $ 70। इस पर निर्भर करता है कि लोग अंतिम स्थान पर हैं, आप अपने खाते में उन दो शेष राशि के साथ समाप्त हो जाएंगे, $ 50 के बजाय आपको ($ 100 - $ 20 - $ 30) समाप्त होना चाहिए। इस मामले में, "आपके पक्ष में बैंक त्रुटि"
अब, मान लीजिए कि आप ताले का उपयोग करते हैं। आपका बिल भुगतान ($ 20) पहले पाइप को हिट करता है, इसलिए यह आपके खाते के रिकॉर्ड को जीतता है और लॉक करता है। अब आपको अनन्य उपयोग मिल गया है, और शेष राशि से $ 20 घटा सकते हैं, और नए शेष राशि को शांति से लिख सकते हैं ... और आपका खाता $ 80 तक समाप्त हो जाएगा जैसा कि अपेक्षित है। लेकिन ... उह ... आप रिसीवर के खाते को अपडेट करने की कोशिश करते हैं, और यह बंद है, और कोड की तुलना में लंबे समय तक लॉक रहता है, आपके लेनदेन का समय समाप्त हो जाता है ... हम बेवकूफ बैंकों के साथ काम कर रहे हैं, इसलिए उचित त्रुटि होने के बजाय हैंडलिंग, कोड सिर्फ एक खींचता है exit()
, और आपका $ 20 इलेक्ट्रॉनों के कश में गायब हो जाता है। अब आप $ 20 से बाहर हो गए हैं, और आपके पास अभी भी रिसीवर के लिए $ 20 बकाया है, और आपका टेलीफोन फिर से तैयार हो जाता है।
इसलिए ... लेनदेन दर्ज करें। आप एक लेन-देन शुरू करते हैं, आप अपने खाते को $ 20 डेबिट करते हैं, आप 20 डॉलर के साथ रिसीवर को क्रेडिट करने की कोशिश करते हैं ... और फिर से कुछ चल रहा है। लेकिन इस बार, इसके बजाय exit()
, कोड बस कर सकता है rollback
, और Poof, आपका $ 20 जादुई रूप से आपके खाते में वापस जोड़ दिया जाता है।
अंत में, यह इस पर उबलता है:
ताले किसी भी अन्य डेटाबेस रिकॉर्ड के साथ हस्तक्षेप करने से रोकते हैं जो आप के साथ काम कर रहे हैं। लेन-देन किसी "बाद में" त्रुटियों को आपके द्वारा किए गए "पहले" चीजों के साथ हस्तक्षेप करने से रोकते हैं। न तो अकेले गारंटी दे सकते हैं कि चीजें अंत में ठीक काम करती हैं। लेकिन एक साथ, वे करते हैं।
कल के पाठ में: द जॉय ऑफ डेडलॉक