看起来很简单,但我很挣扎。问题是如何锁定表 JOBS 中的单行,其中 JOB_ID = IT_PROG 。我想这样做,因为我想从一个过程中尝试异常,当你尝试更新一个锁定的行时它会显示一条消息。提前感谢您的时间。
答案 0 :(得分:2)
您可以按照其他答案中的说明锁定记录,但在更新此行时 看不到任何异常。
UPDATE
语句将等待锁定释放,即具有SELECT ... FOR UPDATE
提交的会话。之后将执行更新。
您可以管理的唯一例外是DEADLOCK,即
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
答案 1 :(得分:1)
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时获取或者超时已过期),则会引发错误。
答案 2 :(得分:-2)
无法在Oracle中手动锁定行。但是,您可以手动锁定对象。执行DML操作时,会自动在行上放置独占锁,以确保没有其他会话可以更新同一行,或者任何其他DDL操作都可以删除该行 - 其他会话可以随时读取它。
请求锁定行的第一个会话获取它,并且任何其他请求写访问权限的会话必须等待 如果您不想被锁定,这意味着,如果您不想等待,可以使用
Select .... For update ( nowait / wait(n) ) ( skiplocked)
声明