Oracle中的select for update

通常情况下,select语句是不会对数据加锁,不会妨碍影响其他的DMLDDL操作。借助for update子句,我们可以在应用程序的层面手工实现数据加锁保护操作。当只允许一个session进行update的时候, for update十分有用.

select…for update之后,可以使用of子句选择对select的特定数据表进行加锁操作。默认情况下,不使用of子句表示在select所有的数据表中加锁。


select * from test for update; 会对table test进行加锁. 此时只允许当前的session对已经存在的数据进行更新. 但其它session仍可以进行insert的操作.


select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update of a.pkid 只锁定Table1中满足条件的行, 这就是使用of子句的作用. 比较常用于多个表的操作.



加入for update之后,Oracle就要求启动一个新事务,尝试对数据进行加锁。如果当前已经被加锁,默认的行为必然是block等待。使用nowait子句的作用就是避免进行等待,当发现请求加锁资源被锁定未释放的时候,直接报错返回。如果不使用nowait或wait子句, 新的加锁请求会一直hang住, 直到原来的commit或rollback.



select * from test where a=2 for update nowait;
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


或者
select * from test where a=2 for update wait 3; 如果3秒内还是无法加锁则返回错误.


在一个session内可以多次进行select XX for update,然后只需要commit或rollback一次即可释放.

请使用浏览器的分享功能分享到微信等