for update与for update of

“FOR UPDATE OF” 是“行锁”(locks on the row) -- 不存在字段加锁!

这“行锁”的作用

1.始于一个CURSOR 的OPEN时候,

2.终于一个完整的传送 -- COMMIT 或ROLLBACK,而不是CURSOR 的完结(CLOSE your_cursor_name) 。

3>.若有两个CURSOR 对同一“行”(row)中任意字段(column)作出更改(UPDATE),
时间上的后一CURSOR会一直等待,至第一个传送完结为止 -- COMMIT 或ROLLBACK。

4.若不被有效处理,死锁就成形。
例如:执行以下程序于两个session上,第二个session会一直处于等待。。。直至
第一个session执行COMMIT 或ROLLBACK为止。
declare
-- query emp.name
cursor cur_emp
is
select empno, ename, job
from emp
where empno = 7369
for update of ename;
begin
for return_cur in cur_emp
loop
update emp
set ename = 'LHG'
where current of cur_emp;
end loop;
end;

5.防止4的方法之一是加NOWAIT在FOR UPDATE之后。如此,第二个session不会一
直等下去,而是出现ORA-00054 [resource busy and acquire with NOWAIT specified]的讯息。


由此,我自己的FOR UPDATE习惯是,

a.NOWAIT定然跟FOR UPDATE之后。

b.COMMIT必需存在程序结尾。以防死锁成形。

c. EXCEPTION里的ROLLBACK是最基本的需要。

在多数情况下,提取循环中所完成的处理都会修改由游标检查出的行,PL/SQL提供了进行这样处理的一种语法。 这种语法包括两部分——在游标声明部分的FOR UPDATE子句和在UPDATE或DELETE语句中的WHERE CURRENT OF 子句。 通常,SELECT操作将不会对正处理的行执行任何锁定设置,这使得连接到该数据库的其他会话可以改变正在选择的数据。 当确定了活动集以后,在执行OPEN的时刻,ORACLE会截取下该表的一个快照。在此时刻以前所提交的任何更改操作都会在活动集中反映出来。在此时刻以后所进行的任何更改操作,即使已经提交了它们,都不会被反映出来,除非将该游标重新打开(数据可能不一致)。
但是使用FOR UPDATE子句,在OPEN返回以前的活动集的相应行上会加上互斥锁,这些锁会避免其他的会话对活动集中的行进行更改。 直到该语句的事务被commit语句或rollback语句结束为止。

[b]for update of 和for update区别 [/b]
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 for update 锁定两个表的所有记录

4 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update 锁定两个表的中满足条件的行

5. 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 后表的条件锁定相对应的表

[b]关于nowait[/b](如果一定要用FOR UPDATE,建议加上nowait)
当有LOCK冲突时会提示错误并结束statement而不是在那里等待(比如:要查的行已经被其它事务锁了,当前的锁事务与之冲突,加上nowait,当前的事务会结束会提示错误并立即结束 statement再等待).

[b]关于 where current of [/b]
使用FOR UPDATE子句是在游标检索时锁定检索到的行,并对应数据库中的物理行,其中后半句是核心。如果是真正的UPDATE,应该在指明UPDATE子句后使用where current of . 确切的说for update 是为update做检索准备。
如果你想删除或者更新被Select For Update引用的记录,你可以使用Where Current Of语句。
Where Current Of语句允许你更新或者是删除最后由cursor取的记录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值