<स्ट्राइक>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
. के कार्यान्वयन के साथ ।)
कड़ाई से बोलने पर आपको मनमाना मिलता है, वास्तव में यादृच्छिक चयन नहीं। यह एक महत्वपूर्ण अंतर हो सकता है।
आपकी क्वेरी का एक लेखा परीक्षित संस्करण आपके अन्य प्रश्न के मेरे उत्तर में है।