例子:
for update
1 select * from TTable1 for update 锁定表的所有行,只能读不能写
2 select * from TTable1 where pkid = 1 for update 只锁定pkid=1的行
3 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update 锁定两个表的中满足条件的行
4 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update of a.pkid 只锁定Table1中满足条件的行
for update 是把所有的表都锁点 for update of 根据of 后表的条件锁定相对应的表列。
for update nowait
1 select * from TTable1 for update nowait锁定表的所有行,只能读不能写
2 select * from TTable1 where pkid = 1 for update nowait只锁定pkid=1的行
3 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update nowait锁定两个表的中满足条件的行
4 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update of a.pkid nowait只锁定Table1中满足条件的行
for update nowait是把所有的表都锁点 for update of ... nowait根据of 后表的条件锁定相对应的表列。
for update nowait和 for update 都会对所查询到得结果集进行加锁,所不同的是,如果另外一个线程正在修改结果集中的数据:
①for update会进行资源等待,必须等到查询结束后(commit)后,才允许另一个线程进行修改。
②for update nowait 不会进行资源等待,只要发现结果集中有些数据被加锁,立刻返回 “ORA-00054错误,内容是资源正忙, 但指定以 NOWAIT 方式获取资源”。
其中:
OF 子句用于指定即将更新的列,即锁定行上的特定列。
WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。
课外小知识:
“使用FOR UPDATE WAIT”子句的优点如下:
1防止无限期地等待被锁定的行。
2允许应用程序中对锁的等待时间进行更多的控制。
3对于交互式应用程序非常有用,因为这些用户不能等待不确定 。
4 若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告。
4、实际运用
业务场景如下:同一应用分布在两台服务器上,两个应用上有同一个定时任务,两个定时任务会操作同一个资源,为了防止一个定时任务进行的时候另一个定时任务也会获取到这个资源,所以
利用行锁对同一资源进行判断。
①首先创建一个表LOCK_BUS_TAB_FOR_TASK,在表中创建两个字段,如下图:
②在程序开始时进行判断,如果这个锁已被持,程序直接结束,不执行定时任务。
核心代码
调用代码
这就避免了对同一资源的重复操作。