Chinaunix首页 | 论坛 | 博客
  • 博客访问: 261910
  • 博文数量: 32
  • 博客积分: 5090
  • 博客等级: 大校
  • 技术积分: 1260
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-05 22:00
文章分类

全部博文(32)

文章存档

2008年(32)

我的朋友

分类: Oracle

2008-08-08 21:16:44

SELECT FOR UPDATE 相关的知识

   单位里最大连接数很低,但由于历史原因,居然每个dml操作前都要SELECT FOR UPDATE一下,因此会造成LOCK的问题,写此文仅给一些常用FOR UPDATE的人。
        statement: 一个SQL语句。
        session:     一个由ORACLE用户产生的连接,一个用户可以产生多个SESSION ,但相互之间是独立的。
        transaction:所有的改变都可以划分到transaction里,一个transaction包含一个或多个SQL。当一个SESSION建立的时候就是一个TRANSACTION开始的时刻,此后transaction的开始和结束由DCL控制,也就是每个COMMIT/ROLLBACK都标示着一个transaction的结束。
        consistency:是对于statement级别而不是transaction级别来说的。sql statement 得到的数据都是以sql statement开始的IMAGE。
 
        LOCK的基本情况
update, insert ,delete, select ... for update会LOCK相应的ROW 。
只有一个TRANSACTION可以LOCK相应的行,也就是说如果一个ROW已经LOCKED了,那就不能被其他TRANSACTION所LOCK了。
LOCK由statement产生但却由TRANSACTION结尾(commit,rollback),也就是说一个SQL完成后LOCK还会存在,只有在COMMIT/ROLLBACK后才会RELEASE。
 
        SELECT.... FOR UPDATE [OF cols] [NOWAIT];
OF cols
SELECT cols FROM tables [WHERE...] FOR UPDATE [OF cols] [NOWAIT];
前面的FOR UPDATE就不说了,讲下OF
transaction A运行
select a.object_name,a.object_id from wwm2 a,wwm3 b
  2     where b.status='VALID' and a.object_id=b.object_id
  3*   for update of a.status
则transaction B可以对b表wwm3的相应行进行DML操作,但不能对a表wwm2相应行进行DML操作.
反一下看看
transaction A运行
select a.object_name,a.object_id from wwm2 a,wwm3 b
  2     where b.status='VALID' and a.object_id=b.object_id
  3*   for update of b.status
则transaction B可以对a表wwm2的相应行进行DML操作,但不能对b表wwm3相应行进行DML操作.
也就是说LOCK的还是行,只是如果不加OF的话会对所有涉及的表LOCK的,加了OF后只会LOCK OF 字句所在的TABLE.
NOWAIT(如果一定要用FOR UPDATE,我更建议加上NOWAIT)
当有LOCK冲突时会提示错误并结束STATEMENT而不是在那里等待.返回错误是"ORA-00054: resource busy and acquire with NOWAIT specified"
 
另外如下用法也值得推荐,应该酌情考虑使用。
FOR UPDATE WAIT 5
5秒后会提示ORA-30006: resource busy; acquire with WAIT timeout expired
FOR UPDATE NOWAIT SKIP LOCKED;
会提示no rows selected
 
        TABLE  LOCKS
 LOCK TABLE table(s) IN EXCLUSIVE MODE [NOWAIT];
同样也是在transaction结束时才会释放lock。
 
        DEADLOCK
transaction a lock rowA     ,  then  transaction b lock rowB
then transaction a tries to lock rowB, and transaction b tries to lock rowA
也就是说两个transaction都相互试图去lock对方已经lock的ROW,都在等待对方释放自己的lock,这样就使死锁。
deadlock也会有600提示。
阅读(860) | 评论(0) | 转发(0) |
0

上一篇:v$sql v$sqlarea v$sqltext

下一篇:删除表空间

给主人留下些什么吧!~~