关于Oracle中update |
发布时间: 2012/8/21 16:58:03 |
前几天用到Oracle数据库的update更新,对于这个简单问题,却出现了不少问题,所以现将从网上搜索资料及自已的总结罗列在此以备一时之用. 以下所列sql都是基于下表 create table test (name varchar2(30),code varchar2(10),i_d varchar2(10)); 插入数据 - 1. update 更新i_d为1的数据 --方式1 这样可以成功 --方式2 update test set (name,code)=( 注意,这样是不行,update set 必须为子查询,所以需要将其改为 : --方式3 update test set (name,code)=( commit; 2.update 说完了,下面写一下关于for update,for update of 下面的资料是从网上找到的,可是具体的网址现在找不到了,请原谅小弟的粗心,引用人家的东东而不写出处. for update 经常用,而for updade of 却不常用,现在将这两个作一个区分 a. select * from test for update 锁定表的所有行,只能读不能写 b. select * from test where i_d = 1 for update 只锁定i_d=1的行,对于其他的表的其他行却不锁定 下面再创建一个表 create table t (dept_id varchar(10),dept_name varchar2(50)); c. select * from test a join t on a.i_d=t.dept_id for update; 这样则会锁定两张表的所有数据 d. select * from test a join t on a.i_d=t.dept_id where a.i_d=1 for update; 这样则会锁定满足条件的数据 e. select * from test a join t on a.i_d=t.dept_id where a.i_d=1 for update of a.i_d; 注意区分 d与e,e只分锁定表test中满足条件的数据行,而不会锁定表t中的数据,因为之前在procedure中作一个update,而需要update的数据需要关联查询,所以用了for update造成其他用户更新造成阻塞,所以才查到这段资料. for update of 是一个行级锁,这个行级锁,开始于一个cursor 打开时,而终止于事务的commit或rollback,而并非cursor的close. 如果有两个cursor对于表的同一行记录同时进行update,实际上只有一个cursor在执行,而另外一个一直在等待,直至另一个完成,它自己再执行.如果第一个cursor不能被很好的处理,第二个cursor也不主动释放资源,则死锁就此产生. 执行如下代码就会死锁(在两个command window中执行) declare for rec in cur_test loop declare for rec in cur_test loop 注意两个pl/sql块中没有commit; 为了解决这个死锁问题,要么就是第一个块释放资源,要么就是第二块主动放弃.第一次释放资源很简单,那就执行commit或rollback;而让第二块主动放弃,在for update 后加no wait;这样就会报 ORA-00054 [resource busy and acquire with NOWAIT specified 的错误,这样就没有死锁了. 本文出自:亿恩科技【www.enkj.com】 |