FOR UPDATE SKIP LOCKED के लिए आपने जो व्यवहार किया है, उसका वर्णन इस ब्लॉग नोट में किया गया है। मेरी समझ यह है कि अद्यतन के लिए खंड का मूल्यांकन WHERE खंड के बाद किया जाता है। SKIP LOCKED एक अतिरिक्त फ़िल्टर की तरह है जो गारंटी देता है कि जिन पंक्तियों को वापस किया जाएगा, उनमें से कोई भी लॉक नहीं है।
आपका कथन तार्किक रूप से इसके समतुल्य है:card_numbers
. से पहली पंक्ति खोजें और अगर यह लॉक नहीं है तो इसे वापस कर दें। जाहिर है यह वह नहीं है जो आप चाहते हैं।
यहां एक छोटा परीक्षण मामला है जो आपके द्वारा वर्णित व्यवहार को पुन:प्रस्तुत करता है:
SQL> CREATE TABLE t (ID PRIMARY KEY)
2 AS SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 1000;
Table created
SESSION1> select id from t where rownum <= 1 for update skip locked;
ID
----------
1
SESSION2> select id from t where rownum <= 1 for update skip locked;
ID
----------
दूसरे चयन से कोई पंक्ति नहीं लौटाई जाती है। इस समस्या को हल करने के लिए आप कर्सर का उपयोग कर सकते हैं:
SQL> CREATE FUNCTION get_and_lock RETURN NUMBER IS
2 CURSOR c IS SELECT ID FROM t FOR UPDATE SKIP LOCKED;
3 l_id NUMBER;
4 BEGIN
5 OPEN c;
6 FETCH c INTO l_id;
7 CLOSE c;
8 RETURN l_id;
9 END;
10 /
Function created
SESSION1> variable x number;
SESSION1> exec :x := get_and_lock;
PL/SQL procedure successfully completed
x
---------
1
SESSION2> variable x number;
SESSION2> exec :x := get_and_lock;
PL/SQL procedure successfully completed
x
---------
2
चूंकि मैंने स्पष्ट रूप से कर्सर लाया है, केवल एक पंक्ति लौटा दी जाएगी (और केवल एक पंक्ति लॉक हो जाएगी)।