SELECT FOR UPDATE SKIP LOCKED --- 一个未公开但十分有用的特性

SELECT FOR UPDATE SKIP LOCKED 选项是ORACLE的一个未公开的特性,它的含义是SELECT时跳过被锁的记录。

考虑下面的例子:

会话1

SQL> select * from sex_dict ;

 

 SERIAL_NO S SEX_ INPUT_CO

---------- - ---- --------

         1 1     N

         9 0 未知  WZ

         2 2     N

         4 9 未定  WD

SQL> select * from sex_dict  where serial_no = 1 for update ;

 

 SERIAL_NO S SEX_ INPUT_CO

---------- - ---- --------

         1 1     N

 

会话2

查询并锁住serial_no in (1,2) 的记录

SQL> select * from sex_dict where serial_no in ( 1, 2) for update ;

 

此时会话2挂住,直到会话1事务结束。

 

加上”NOWAIT”选项

SQL>  select * from sex_dict where serial_no in ( 1, 2) for update nowait ;

 select * from sex_dict where serial_no in ( 1, 2) for update nowait

               *

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified

因为serial_no = 1的记录被会话锁住,所以这个操作没有成功。

 

加上SKIP LOCKED选项

SQL>  select * from sex_dict where serial_no in ( 1, 2) for update nowait  skip locked;

 

 SERIAL_NO S SEX_ INPUT_CO

---------- - ---- --------

         2 2     N

 

会话2只锁住serial_no=2的记录,跳过serial_no=1的记录。

 

这个特性适合例如消息队列的操作,当消息到达时,处理消息的各个客户选取并锁住一个消息处理,但不能阻塞其它客户处理消息。其它客户则处理没有被锁的消息。这个可以参考AnySQL.net的《Oracle中如何跳过被别人锁住的记录?

利用这个特点,Tomac给出了一个不跳号序列号的方法

猜你喜欢

转载自ihuning.iteye.com/blog/2257767