skip locked 锁不住应该会跳过,怎么还会报这个错呢?不得其解
Skip Locked 主要是为了在多用户环境中使用而设计的。它我们在执行DML语句的时候跳过锁定的行,直接获取未锁定的行。所以理论上你使用了skip locked 应该是获取未锁定的行而不应该是报错。
但有另外一种情况,比如有用户对表进行进行LOCK操作例如
LOCK TABLE XXXX IN EXCLUSIVE MODE。
这时候你再对表进行DML类的操作,例如
select * from XXXX for update skip locked
这时候该语句仍然是被阻塞的。你的错误是否可能是因此而超时导致的报错?
Oracle Skip Locked
Oracle 11g引入skip locked。
Skip Locked 是在query select语句中跳过已经被其他正在执行的query select语句锁住的行,只执行能够获得锁的行。
select for update如何查询大数量,那么其他session同时执行的select语句可能会等待锁超时而报下面这个错
ORA-30006: resource busy; acquire with WAIT timeout expired
如果是不超时的case,那么会出现
ORA-00054 resource busy and NOWAIT specified
比如session1执行下面语句:
SELECT *
FROM dept WHERE
deptno = 10
FOR UPDATE NOWAIT;
输出:
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
session2执行下面语句:
SELECT * FROM dept
WHERE deptno IN (10,20)
FOR UPDATE NOWAIT;
那么输出:
SELECT * FROM dept WHERE deptno IN (10,20)
FOR UPDATE NOWAIT
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified
因为session1已经锁住10这一行,session2请求获得不到10这一行的锁,就报错了。
那么在session2我们可以使用skip locked
SELECT * FROM dept
WHERE deptno IN (10,20)
FOR UPDATE SKIP LOCKED;
此时输出:
DEPTNO DNAME LOC
---------- -------------- -------------
20 RESEARCH DALLAS
SKIP LOCKED会跳过被锁住的行,只查询没有锁住的行。