1、select for update
select for update 是对查询出来的数据进行加锁,当执行select for update时,如果还没有执行Commit时,是不能对查询出来的记录进行select for update、UPDATE 和 DELETE等操作,只有等到事务提交了才可以。但是对于表来说是可以进行insert into操作的。
例如:Select restnum from book where id =1 for update ; -- 给 id=1 的行加上排它锁且 id 有索引
Update book set restnum=restnum-1 where id=1 ;
在进行后面的UPDATE时,会一直处于执行状态,等待挂起的状态。
由此,我们可以获取到结论:for update子句的默认行为就是自动启动一个事务,借助事务的锁机制将数据进行锁定。
2、select for update Nowait子句
当我们进行for update的操作时,与普通select存在很大不同。一般select是不需要考虑数据是否被锁定,最多根据多版本一致读的特性读取之前的版本。加入for update之后,Oracle就要求启动一个新事务,尝试对数据进行加锁。如果当前已经被加锁,默认的行为必然是block等待。
使用nowait子句的作用就是避免进行等待,当发现请求加锁资源被锁定未释放的时候,直接报错返回。
//变换session,进行执行。
SQL> select * from emp for update nowait;
select * from emp for update nowait
ORA-00054:资源正忙,但指定以NOWAIT方式获取资源,或者超时失效
对应的还有就是wait子句,也就是默认的for update行为。一旦发现对应资源被锁定,就等待blocking,直到资源被释放或者用户强制终止命令。