SELECT a.*,a.rowid FROM table a;
语句运行时,并没有给数据加上行级锁,其他人可以对数据进行编辑,提交的瞬间完成上锁,提交,解锁等动作。所以用ROWID来定位记录是最快的,比索引还快,不会锁表,当多人对表进行操作的时候,并不会产生无法操作的现象。
SELECT * FROM table a for update;
语句运行时,会对所查询到得结果集进行加锁,不允许其他程序修改;当其他人忘记提交或者回滚事务的时候,就会发生锁表,只适合单人进行操作,不适合多人同时操作;
SELECT * FROM table a for update nowait;
不会进行资源等待,也会对所查询到得结果集进行加锁,别的线程对结果集进行操作时会报错"ORA-00054",提示:内容是资源正忙, 但指定以 NOWAIT 方式获取资源。(适合自己操作优先)
for update nowait和 for update 都会对所查询到得结果集进行加锁,所不同的是,如果另外一个线程正在修改结果集中的数据,for update nowait 不会进行资源等待,只要发现结果集中有些数据被加锁,立刻返回 "ORA-00054"错误,内容是资源正忙, 但指定以 NOWAIT 方式获取资源”。
for update 和 for update nowait 加上的是一个行级锁,也就是只有符合where条件的数据被加锁。如果仅仅用update语句来更改数据时,可能会因为加不上锁而没有响应地、莫名其妙地等待,但如果在此之前,for update nowait语句将要更改的数据试探性地加锁,就可以通过立即返回的错误提示而明白其中的道理,或许这就是for update和for update nowait的意义之所在。
这里需要注意的是for update和for update nowait语句在同一session中只要使用一次就能锁住对应表的对应记录直到该session结束,意思是在一个session中如果对一张表update多次时只要进行一次lock的检查。操作此语句最好加上where条件,加上只会对条件中的数据进行加锁,不加where则会对整个表加锁;