两个问题:
一、oracle默认在update时是行锁。但如果update的where条件中有函数在使用,这时是行锁还是表锁?
以sql server举例:
update table set column1=1 whrere WorkDate='2011-3-5';行锁
update table set column1=1 whrere Convert(Char(10),[WorkDate],120)='2011-3-5';表锁同种情况下,在oracle中会产生何种锁?二、在sql server中可以用--开事务, 以保持锁
BEGIN TRAN -- 更新
update table a
set column1 = 1
where idx = 1
-- 列出锁信息
EXEC sp_lock @@spid
来测试一个语句将会产生什么类型的锁,oracle中有没有这种可以检测语句的方法?
一、oracle默认在update时是行锁。但如果update的where条件中有函数在使用,这时是行锁还是表锁?
以sql server举例:
update table set column1=1 whrere WorkDate='2011-3-5';行锁
update table set column1=1 whrere Convert(Char(10),[WorkDate],120)='2011-3-5';表锁同种情况下,在oracle中会产生何种锁?二、在sql server中可以用--开事务, 以保持锁
BEGIN TRAN -- 更新
update table a
set column1 = 1
where idx = 1
-- 列出锁信息
EXEC sp_lock @@spid
来测试一个语句将会产生什么类型的锁,oracle中有没有这种可以检测语句的方法?
SQL> update emp set sal=8000 where empno=7369;1 row updatedSQL> select sid,type,lmode from v$lock where sid=146; SID TYPE LMODE
---------- ---- ----------
146 TM 3
146 TX 6SQL> rollback;Rollback completeSQL> update emp set sal=8000 where to_char(hiredate,'yyyy-mm-dd')='1980-12-17';1 row updatedSQL> select sid,type,lmode from v$lock where sid=146; SID TYPE LMODE
---------- ---- ----------
146 TM 3
146 TX 6SQL> rollback;Rollback completeSQL> 都会产生两种锁 TM,TX 即表锁和行锁
update emp set sal=8000这样整表更新和update emp set sal=8000 where empno=7369执行
select sid,type,lmode from v$lock where sid=***时为什么返回都一样?都是
SID TYPE LMODE
---------- ---- ----------
*** TM 3
*** TX 6
这好像不应该吧。整表更新应该是表锁。而特定明确条件更新应该是行锁。这是我自己理解,不知能否给我答案。谢谢
同时,会在表上产生一个表锁,表锁是阻止对表进行DDL操作,比如增删列,删除表等等。
所以全表更新和带条件更新都产生两种锁
下周结帖,这其间还希望有更多的朋友进来发表自己的见解。
产生这种疑问的原因是,这几天在处理一个sql server 2000的存储过程时,遇到了一个问题,不同的用户调用这个存储过程时是针对同一个表但不同记录进行进行update,导致死锁。以前在用oracle时并没有遇到这种问题。后来根据测试发现sql server在执行update table set column1=1 whrere Convert(Char(10),[WorkDate],120)='2011-3-5'时,就成了表锁,这个时候再update表中的其它记录就会死锁了。
因为有了这个情况,所以我想确定一下在同种操作时oracle是否也会出现此类问题。
同种操作是什么意思呢?两句update语句在oracle里面是会死锁的,不过要构造一个比较特殊的表和一些索引。当然就算构造出来,实际运行中出现死锁的机会也比较少。update语句对多行数据加锁不是一个原子的操作,加锁的顺序是按照索引来的(这个做过实验),没有索引的话就不知道了。