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

लॉक की गई पंक्तियों की प्रतीक्षा से बचने के लिए एडवाइजरी लॉक या NOWAIT?

<स्ट्राइक>FOR UPDATE NOWAIT केवल एक अच्छा विचार है यदि आप किसी विशेष पंक्ति को लॉक करने पर जोर देते हैं, जो कि नहीं है जिसकी आपको जरूरत है। आप बस कोई भी चाहते हैं योग्यता, उपलब्ध (अनलॉक) पंक्ति। महत्वपूर्ण अंतर यह है (पोस्टग्रेज 9.4 के लिए मैनुअल को उद्धृत करते हुए):

<ब्लॉकक्वॉट>

NOWAIT . के साथ , यदि चयनित पंक्ति को तुरंत लॉक नहीं किया जा सकता है, तो स्टेटमेंट प्रतीक्षा करने के बजाय त्रुटि की रिपोर्ट करता है।

समान प्रश्नों की संभावना समान मनमानी पिक को लॉक करने का प्रयास करेगी। FOR UPDATE NOWAIT बस एक अपवाद के साथ जमानत मिल जाएगी (जो पूरे लेन-देन को वापस ले लेगा जब तक कि आप त्रुटि को नहीं पकड़ते) और आपको पुनः प्रयास करना होगा।

dba.SE पर मेरे संदर्भित उत्तर में समाधान सादे FOR UPDATE के संयोजन का उपयोग करता है pg_try_advisory_lock() . के संयोजन में :

<ब्लॉकक्वॉट>

pg_try_advisory_lock pg_advisory_lock . के समान है , फ़ंक्शन को छोड़कर लॉक उपलब्ध होने की प्रतीक्षा नहीं करेगा। यह या तो तुरंत लॉक प्राप्त करेगा और सही लौटाएगा, या यदि लॉक तुरंत प्राप्त नहीं किया जा सकता है तो यह झूठा लौटाएगा।

तो आपका सर्वश्रेष्ठ विकल्प है ... तीसरा विकल्प:नया FOR UPDATE SKIP LOCKED Postgres 9.5 में, जो अतिरिक्त फ़ंक्शन कॉल के बिना समान व्यवहार को लागू करता है।

Postgres 9.5 के लिए मैनुअल दो विकल्पों की तुलना करता है, अंतर को कुछ और समझाता है:

<ब्लॉकक्वॉट>

संचालन को अन्य लेन-देन के लिए प्रतीक्षा करने से रोकने के लिए, NOWAIT . का उपयोग करें या SKIP LOCKED विकल्प। NOWAIT . के साथ , यदि चयनित पंक्ति को तुरंत लॉक नहीं किया जा सकता है, तो स्टेटमेंट प्रतीक्षा करने के बजाय त्रुटि की रिपोर्ट करता है। SKIP LOCKED के साथ , कोई भी चुनी हुई पंक्तियाँ जिन्हें तुरंत लॉक नहीं किया जा सकता, छोड़ दी जाती हैं।

Postgres 9.4 या पुराने पर आपका अगला सबसे अच्छा विकल्प का उपयोग करना है pg_try_advisory_xact_lock(id) FOR UPDATE . के संयोजन में जैसा कि संदर्भित उत्तर में दिखाया गया है:

  • अद्यतन पोस्ट करता है ... सीमा 1

(साथ ही FOR UPDATE SKIP LOCKED . के कार्यान्वयन के साथ ।)

अलग

कड़ाई से बोलने पर आपको मनमाना मिलता है, वास्तव में यादृच्छिक चयन नहीं। यह एक महत्वपूर्ण अंतर हो सकता है।
आपकी क्वेरी का एक लेखा परीक्षित संस्करण आपके अन्य प्रश्न के मेरे उत्तर में है।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ड्रॉप कॉलम कॉलम संदर्भों को पूरी तरह से नहीं हटाता है - postgresql

  2. dplyr left_join से कम, शर्त से बड़ा

  3. SQLalchemy भूमिका निर्धारित करते समय परिवर्तन नहीं कर रहा है

  4. पूर्णांकों का विभाजन 0 . लौटाता है

  5. पॉइंट इन टाइम रिकवरी का उपयोग करके अपने पोस्टग्रेएसक्यूएल डेटाबेस के लिए आरपीओ को कम कैसे करें