请求锁定需要排队。如果某个会话请求一个锁定,但由于其他会话已经锁定好了指定行或对象儿无法获得所需的锁定,那么这个会话将会等待。此时,可能有多个会话都在等待访问相同的记录或对象,在这种情况下,oracle会跟踪这些会话请求锁定的顺序。当使用锁定的会话解除锁定时,下一个会话就会获得授权,以此类推,这种机制被称为“排队enqueue”机制。
如果不希望某个会话在无法获取锁定的时候进行排队,那么避免排队的唯一方式是使用SELECT ...FOR UPDATE命令的WAIT或
NOWAIT子句。因为SELECT语句并不需要任何锁定,所以普通的SELECT 语句可以成功地执行。但是,DML语句则会被挂起。
SELECT... FOR UPDATE命令会采用排他模式来选择和锁定记录。如果某行已经被锁定,那么在锁定被释放之前,SELECT ... FOR UPDATE语句会像DML语句一样进行排队并挂起会话。使用SELECT ...FOR UPDATE NOWAIT或
SELECT ... FOR UPDATE WAIT就可以避免挂起会话,其中是以秒为单位的数值。使用SELECT ... FOR UPDATE选项中的
一个获得锁定之后,我们就可以在不必挂起会话的情况下执行DML命令。
打开一个会话,向表t插入一条记录并提交:
HR@orcl 23-OCT-14>insert into t values(1);
1 row created.
HR@orcl 23-OCT-14>commit;
Commit complete.
使用select...for update子句:
HR@orcl 23-OCT-14>select * from t for update;
ID
----------
1
1 row created.
HR@orcl 23-OCT-14>commit;
Commit complete.
使用select...for update子句:
HR@orcl 23-OCT-14>select * from t for update;
ID
----------
1
打开另一个会话,同样执行select * from t for update;
HR@orcl 23-OCT-14>select * from t for update;
该回话就会被挂起。
当一个会话在一个对象上使用语句select ... for update;时,另一个会话也在同一个对象上执行
select ... for update;就会被挂起。
要等到第一个会话提交或者回滚之后,第二个会话才可以继续:
第二个会话:
但是如果我们使用的是select ... for update nowait;的话,另一个会话就不会被挂起,而是会直接返回一个ORA-00054的错误,同时也可以告诉别人,我正在改着,你要等等:
第二个会话:
HR@orcl 23-OCT-14>select * from t for update nowait;
select * from t for update nowait
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
select * from t for update nowait
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
另外,可以将关键字SKIP LOCKED 附加到SELECT FOR UPDATE语句后,这样将返回且锁定并未由另一个会话锁定的行。早期的版本中就存在此命令,但从11g开始才对其进行支持。
在第一个会话中向表t插入第二条记录并提交:
HR@orcl 23-OCT-14>insert into t values(2);
1 row created.
HR@orcl 23-OCT-14>commit;
Commit complete.
HR@orcl 23-OCT-14>select * from t;
ID
----------
1
2
1 row created.
HR@orcl 23-OCT-14>commit;
Commit complete.
HR@orcl 23-OCT-14>select * from t;
ID
----------
1
2
此时第一条记录已经被锁定了。
在第二个会话中执行:
通过这个命令我们可以看到表t中没有被锁定的第二条记录了。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29800581/viewspace-1308866/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29800581/viewspace-1308866/