Beteendet du har stött på för FÖR UPPDATERING SKIP LÅST har beskrivits i den här blogganteckningen. Jag förstår att FOR UPDATE-satsen utvärderas EFTER WHERE-satsen. SKIP LOCKED är som ett extra filter som garanterar att ingen av raderna som skulle ha returnerats är låsta.
Ditt påstående motsvarar logiskt:hitta den första raden från card_numbers
och lämna tillbaka den om den inte är låst. Uppenbarligen är detta inte vad du vill.
Här är ett litet testfall som återger beteendet du beskriver:
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
----------
Ingen rad returneras från det andra valet. Du kan använda en markör för att kringgå det här problemet:
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
Eftersom jag uttryckligen har hämtat markören kommer endast en rad att returneras (och endast en rad kommer att låsas).