如何在 Oracle SQL 中锁定单行
How can I lock a single row in Oracle SQL
这看起来很简单,但我很难做到。问题是我如何锁定 table JOBS 中的一行 JOB_ID = IT_PROG.我想这样做,因为我想尝试一个过程的异常,当您尝试更新锁定的行时,它会向您显示一条消息。提前感谢您的宝贵时间。
AskTom 有一个您尝试执行的示例:
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:4515126525609
来自 AskTom:
declare
resource_busy exception;
pragma exception_init( resource_busy, -54 );
success boolean := False;
begin
for i in 1 .. 3
loop
exit when (success);
begin
select xxx from yyy where .... for update NOWAIT;
success := true;
exception
when resource_busy then
dbms_lock.sleep(1);
end;
end loop;
if ( not success ) then
raise_application_error( -20001, 'row is locked by another session' );
end if;
end;
这会尝试获取锁,如果无法获取锁(即 ORA-00054:资源繁忙并使用指定的 NOWAIT 获取或引发超时),它将引发错误。
您可以按照其他答案中的描述锁定记录,但是在更新此行时您将看不到任何异常。
UPDATE
语句将等待直到锁被释放,即 SELECT ... FOR UPDATE
的会话提交。之后将执行更新。
您唯一可以管理的例外是死锁,即
Session1 SELECT FOR UPDATE record A
Session2 SELECT FOR UPDATE record B
Session1 UPDATE record B --- wait as record locked
Session2 UPDATE record A --- deadlock as 1 is waiting on 2 and 2 waiting on 1
无法在 Oracle 中手动锁定行。不过,您可以手动锁定对象。排他锁在执行 DML 操作时自动放置在行上,以确保没有其他会话可以更新同一行或任何其他 DDL 操作可以删除该行 - 其他会话可以随时读取它。
第一个请求锁定行的会话获得它,任何其他请求写访问的会话必须等待。
如果你不想被锁定,也就是说,如果你不想等待,你可以使用
Select .... For update ( nowait / wait(n) ) ( skiplocked)
声明
这看起来很简单,但我很难做到。问题是我如何锁定 table JOBS 中的一行 JOB_ID = IT_PROG.我想这样做,因为我想尝试一个过程的异常,当您尝试更新锁定的行时,它会向您显示一条消息。提前感谢您的宝贵时间。
AskTom 有一个您尝试执行的示例:
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:4515126525609
来自 AskTom:
declare
resource_busy exception;
pragma exception_init( resource_busy, -54 );
success boolean := False;
begin
for i in 1 .. 3
loop
exit when (success);
begin
select xxx from yyy where .... for update NOWAIT;
success := true;
exception
when resource_busy then
dbms_lock.sleep(1);
end;
end loop;
if ( not success ) then
raise_application_error( -20001, 'row is locked by another session' );
end if;
end;
这会尝试获取锁,如果无法获取锁(即 ORA-00054:资源繁忙并使用指定的 NOWAIT 获取或引发超时),它将引发错误。
您可以按照其他答案中的描述锁定记录,但是在更新此行时您将看不到任何异常。
UPDATE
语句将等待直到锁被释放,即 SELECT ... FOR UPDATE
的会话提交。之后将执行更新。
您唯一可以管理的例外是死锁,即
Session1 SELECT FOR UPDATE record A
Session2 SELECT FOR UPDATE record B
Session1 UPDATE record B --- wait as record locked
Session2 UPDATE record A --- deadlock as 1 is waiting on 2 and 2 waiting on 1
无法在 Oracle 中手动锁定行。不过,您可以手动锁定对象。排他锁在执行 DML 操作时自动放置在行上,以确保没有其他会话可以更新同一行或任何其他 DDL 操作可以删除该行 - 其他会话可以随时读取它。
第一个请求锁定行的会话获得它,任何其他请求写访问的会话必须等待。
如果你不想被锁定,也就是说,如果你不想等待,你可以使用
Select .... For update ( nowait / wait(n) ) ( skiplocked)
声明