Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

क्या अद्यतन के लिए चयन पंक्ति मौजूद नहीं होने पर अन्य कनेक्शन डालने से रोकता है?

MySQL

चुनें ... अद्यतन के साथ अद्यतन के लिए

InnoDB (ऑटो-कमिट बंद) के साथ लेन-देन का उपयोग करना, एक SELECT ... FOR UPDATE एक सत्र को किसी विशेष रिकॉर्ड (या रिकॉर्ड) को अस्थायी रूप से लॉक करने की अनुमति देता है ताकि कोई अन्य सत्र इसे अपडेट न कर सके। फिर, उसी लेन-देन के भीतर, सत्र वास्तव में एक UPDATE प्रदर्शन कर सकता है उसी रिकॉर्ड पर और लेनदेन को प्रतिबद्ध या वापस रोल करें। यह आपको रिकॉर्ड को लॉक करने की अनुमति देगा ताकि कोई अन्य सत्र इसे अपडेट न कर सके, जबकि शायद आप कुछ अन्य व्यावसायिक तर्क करते हैं।

यह लॉकिंग के साथ पूरा किया जाता है। InnoDB रिकॉर्ड को लॉक करने के लिए इंडेक्स का उपयोग करता है, इसलिए मौजूदा रिकॉर्ड को लॉक करना आसान लगता है - बस उस रिकॉर्ड के लिए इंडेक्स को लॉक करें।

चुनें ... INSERT के साथ अपडेट के लिए

हालांकि, उपयोग करने के लिए SELECT ... FOR UPDATE INSERT . के साथ , आप किसी ऐसे रिकॉर्ड के लिए इंडेक्स को कैसे लॉक करते हैं जो अभी तक मौजूद नहीं है? यदि आप REPEATABLE READ . के डिफ़ॉल्ट आइसोलेशन स्तर का उपयोग कर रहे हैं , InnoDB गैप . का भी उपयोग करेगा ताले जब तक आप id . जानते हैं (या आईडी की रेंज भी) लॉक करने के लिए, फिर InnoDB गैप को लॉक कर सकता है ताकि उस गैप में कोई अन्य रिकॉर्ड तब तक नहीं डाला जा सके जब तक कि हम इसके साथ काम नहीं कर लेते।

अगर आपका id कॉलम एक ऑटो-इन्क्रीमेंट कॉलम था, फिर SELECT ... FOR UPDATE INSERT INTO . के साथ समस्याग्रस्त होगा क्योंकि आपको नहीं पता होगा कि नया id क्या है जब तक आप इसे सम्मिलित नहीं करते थे। हालाँकि, चूंकि आप id जानते हैं जिसे आप सम्मिलित करना चाहते हैं, SELECT ... FOR UPDATE INSERT . के साथ काम करेगा।

चेतावनी

डिफ़ॉल्ट आइसोलेशन स्तर पर, SELECT ... FOR UPDATE गैर-मौजूद रिकॉर्ड पर नहीं अन्य लेनदेन को रोकें। इसलिए, यदि दो लेन-देन दोनों एक करते हैं SELECT ... FOR UPDATE एक ही गैर-मौजूद इंडेक्स रिकॉर्ड पर, वे दोनों लॉक प्राप्त करेंगे, और न ही लेनदेन रिकॉर्ड को अपडेट करने में सक्षम होंगे। वास्तव में, यदि वे कोशिश करते हैं, तो एक गतिरोध का पता चल जाएगा।

इसलिए, यदि आप गतिरोध से निपटना नहीं चाहते हैं, तो आप बस निम्न कार्य कर सकते हैं:

इसमें डालें ...

लेन-देन शुरू करें, और INSERT निष्पादित करें . अपना व्यावसायिक तर्क करें, और या तो लेन-देन करें या रोलबैक करें। जैसे ही आप INSERT करते हैं पहले लेन-देन पर गैर-मौजूद रिकॉर्ड अनुक्रमणिका पर, अन्य सभी लेन-देन ब्लॉक हो जाएंगे यदि वे INSERT करने का प्रयास करते हैं एक ही अद्वितीय सूचकांक के साथ एक रिकॉर्ड। यदि पहला लेनदेन सम्मिलित करने के बाद दूसरा लेनदेन उसी सूचकांक के साथ एक रिकॉर्ड डालने का प्रयास करता है, तो उसे "डुप्लिकेट कुंजी" त्रुटि मिलेगी। तदनुसार संभालें।

चुनें ... शेयर मोड में लॉक करें

यदि आप LOCK IN SHARE MODE . के साथ चयन करते हैं INSERT . से पहले , यदि पिछले लेन-देन ने वह रिकॉर्ड डाला है लेकिन अभी तक प्रतिबद्ध नहीं किया है, तो SELECT ... LOCK IN SHARE MODE पिछला लेन-देन पूरा होने तक अवरुद्ध रहेगा।

इसलिए डुप्लीकेट कुंजी त्रुटियों की संभावना को कम करने के लिए, विशेष रूप से यदि आप व्यापार तर्क करने या उन्हें वापस रोल करने से पहले कुछ समय के लिए ताले को पकड़ते हैं:

  1. SELECT bar FROM FooBar WHERE foo = ? LOCK FOR UPDATE
  2. यदि कोई रिकॉर्ड नहीं लौटा, तो
  3. INSERT INTO FooBar (foo, bar) VALUES (?, ?) में डालें


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. हाइबरनेट, आईडी, ओरेकल, अनुक्रम

  2. आरएसी अनुक्रम विवाद

  3. जब ऑरैकल डीबी में फारसी चरित्र डालें तो मुझे प्रश्न चिह्न दिखाई देता है

  4. DBA_TABLES से गणना (*) बनाम NUM_ROWS द्वारा तालिका की Oracle पंक्ति गणना

  5. ORA-01461:केवल एक लंबे कॉलम में डालने के लिए एक लंबा मान बांध सकता है-क्वेरी करते समय होता है