如何在Oracle SQL中锁定单行

时间:2016-01-13 20:02:09

标签: sql oracle row locked

看起来很简单,但我很挣扎。问题是如何锁定表 JOBS 中的单行,其中 JOB_ID = IT_PROG 。我想这样做,因为我想从一个过程中尝试异常,当你尝试更新一个锁定的行时它会显示一条消息。提前感谢您的时间。

3 个答案:

答案 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)声明