我遇到了我正在使用带有FOR UPDATE SKIP LOCKED的select语句的情况。 下面的查询是从RAC环境中运行的多个并行Jjobs调用的过程的一部分:
CURSOR MyCursor IS
SELECT A.ID, A.NEXTSEQNBR, A.EVENTTYPCD, A.EVMEVENTID , B.EVENTTTIMESTAMP
FROM Table1 A
INNER JOIN Table2 B ON A.ID = B.ID
AND A.NEXTSEQNBR - 1 = B.SEQNBR
WHERE B.STATCD = 'MYVAL'
AND MOD(A.ID, 1 ) = 0
FOR UPDATE SKIP LOCKED;
Table1有一个名为EVENTTYPTABLE1的主表。 Table1.EVENTTYPCD列是引用EVENTTYPTABLE1的外键。
在生产环境中,我正在检查锁定的对象,发现主表EVENTTYPTABLE1正在被锁定,即使我在上面的查询中没有使用主表EVENTTYPTABLE1。我期待Table1和Table2表处于锁定状态,因为FOR UPDATE SKIP LOCKED。但为什么EVENTTYPTABLE1?我错过了什么?
当然正在程序中打开和提取光标。
答案 0 :(得分:2)
这取决于您对所选数据的处理方式。您的Cursor包含外键列A.EVENTTYPCD
。如果您的进程更新了该列,您将在父表上看到行独占(RX)AKA子代理表(SX)锁定:
LOCK_TYPE LMODE OBJECT_NAME
--------- ------------- --------------
TM row-X (SX) EVENTTYPTABLE1
TM row-X (SX) EVENTTYPTABLE1
TM row-X (SX) TABLE1
TM row-X (SX) TABLE1
TX exclusive (X)
但如果进程没有触及外键,则不会
LOCK_TYPE LMODE OBJECT_NAME
--------- ------------- --------------
TM row-X (SX) TABLE1
TX exclusive (X)
Oracle在11.1.0.6中引入了这种行为来修复bug。它记录在Oracle Support Note,5909305.8中。在未经Oracle许可的情况下发布支持说明(或任何其他MOS材料)是违反Oracle支持技术支持,但您应该尝试使用谷歌搜索;)