oracle 行锁 表锁

虾片儿 2011-03-24 03:26:47
两个问题:
一、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中有没有这种可以检测语句的方法?
...全文
1871 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
palm_civet 2011-03-26
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 chinalobster 的回复:]

如果将where中的函数去掉,也就是将语句改成update table set column1=1 whrere [WorkDate]='2011-3-5'就是行级锁,就不会出现死锁。
因为有了这个情况,所以我想确定一下在同种操作时oracle是否也会出现此类问题。
[/Quote]

同种操作是什么意思呢?两句update语句在oracle里面是会死锁的,不过要构造一个比较特殊的表和一些索引。当然就算构造出来,实际运行中出现死锁的机会也比较少。update语句对多行数据加锁不是一个原子的操作,加锁的顺序是按照索引来的(这个做过实验),没有索引的话就不知道了。

一生望云 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 chinalobster 的回复:]
如果将where中的函数去掉,也就是将语句改成update table set column1=1 whrere [WorkDate]='2011-3-5'就是行级锁,就不会出现死锁。
因为有了这个情况,所以我想确定一下在同种操作时oracle是否也会出现此类问题。
[/Quote]
不会
一生望云 2011-03-24
  • 打赏
  • 举报
回复
嗯,是的。而且行级锁也就只有这一种类型锁就是X锁(排它锁)
虾片儿 2011-03-24
  • 打赏
  • 举报
回复
如果将where中的函数去掉,也就是将语句改成update table set column1=1 whrere [WorkDate]='2011-3-5'就是行级锁,就不会出现死锁。
因为有了这个情况,所以我想确定一下在同种操作时oracle是否也会出现此类问题。
虾片儿 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 hurui1227 的回复:]

在对表一行或多行进行更新时,会在行上产生行级锁,其他会话就不能对锁定的行进行DML操作,
同时,会在表上产生一个表锁,表锁是阻止对表进行DDL操作,比如增删列,删除表等等。
所以全表更新和带条件更新都产生两种锁
[/Quote]
是不是也可以这样理解,在oracle中,无论做何种update,针对于记录来说,只有行级锁?
产生这种疑问的原因是,这几天在处理一个sql server 2000的存储过程时,遇到了一个问题,不同的用户调用这个存储过程时是针对同一个表但不同记录进行进行update,导致死锁。以前在用oracle时并没有遇到这种问题。后来根据测试发现sql server在执行update table set column1=1 whrere Convert(Char(10),[WorkDate],120)='2011-3-5'时,就成了表锁,这个时候再update表中的其它记录就会死锁了。
虾片儿 2011-03-24
  • 打赏
  • 举报
回复
非常感谢hurui1227的解释。
下周结帖,这其间还希望有更多的朋友进来发表自己的见解。
一生望云 2011-03-24
  • 打赏
  • 举报
回复
在对表一行或多行进行更新时,会在行上产生行级锁,其他会话就不能对锁定的行进行DML操作,
同时,会在表上产生一个表锁,表锁是阻止对表进行DDL操作,比如增删列,删除表等等。
所以全表更新和带条件更新都产生两种锁
虾片儿 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hurui1227 的回复:]

SQL code

SQL> update emp set sal=8000 where empno=7369;

1 row updated

SQL> select sid,type,lmode from v$lock where sid=146;

SID TYPE LMODE
---------- ---- ----------
146 TM ……
[/Quote]
我试了一下,
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
这好像不应该吧。整表更新应该是表锁。而特定明确条件更新应该是行锁。这是我自己理解,不知能否给我答案。谢谢

  • 打赏
  • 举报
回复
[Quote=引用 2 楼 chinalobster 的回复:]
引用 1 楼 zhuomingwang 的回复:

刚测试了下 是行级锁

我这可是两个问题。而且不知道您测试的是哪一个语句?
[/Quote]
第一个~ 后面的没看
一生望云 2011-03-24
  • 打赏
  • 举报
回复

SQL> update emp set sal=8000 where empno=7369;

1 row updated

SQL> select sid,type,lmode from v$lock where sid=146;

SID TYPE LMODE
---------- ---- ----------
146 TM 3
146 TX 6

SQL> rollback;

Rollback complete

SQL> update emp set sal=8000 where to_char(hiredate,'yyyy-mm-dd')='1980-12-17';

1 row updated

SQL> select sid,type,lmode from v$lock where sid=146;

SID TYPE LMODE
---------- ---- ----------
146 TM 3
146 TX 6

SQL> rollback;

Rollback complete

SQL>

都会产生两种锁 TM,TX 即表锁和行锁
虾片儿 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zhuomingwang 的回复:]

刚测试了下 是行级锁
[/Quote]
我这可是两个问题。而且不知道您测试的是哪一个语句?
  • 打赏
  • 举报
回复
刚测试了下 是行级锁

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧