ITPub博客

首页 > 数据库 > Oracle > oracle数据库锁表相关知识

oracle数据库锁表相关知识

Oracle 作者:qinqin859 时间:2014-02-20 10:54:39 0 删除 编辑
1.oracle中锁的分类
oracle里的锁分为DDL,DML锁
DML锁又可以分为,行锁、表锁、死锁
行锁:当事务执行数据库插入、更新、删除操作时,该事务自动获得操作表中操作行的排它锁。
表级锁:当事务获得行锁后,此事务也将自动获得该行的表锁(共享锁),以防止其它事务进行DDL语句影响记录行的更新。事务也可以在进行过程中获得共享锁或排它锁,只有当事务显示使用LOCK TABLE语句显示的定义一个排它锁时,事务才会获得表上的排它锁,也可使用LOCK TABLE显示的定义一个表级的共享锁(LOCK TABLE具体用法请参考相关文档)。
死锁:当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就出现死锁。
如事务1在表A行记录#3中有一排它锁,并等待事务2在表A中记录#4中排它锁的释放,而事务2在表A记录行#4中有一排它锁,并等待事务1在表A中记录#3中排它锁的释放,事务1与事务2彼此等待,因此就造成了死锁。死锁一般是因拙劣的事务设计而产生。

DDL锁又可以分为:排它DDL锁、共享DDL锁、分析锁 
排它DDL锁:创建、修改、删除一个数据库对象的DDL语句获得操作对象的 排它锁。如使用alter table语句时,为了维护数据的完成性、一致性、合法性,该事务获得一排它DDL锁。
共享DDL锁:需在数据库对象之间建立相互依赖关系的DDL语句通常需共享获得DDL锁。
如创建一个包,该包中的过程与函数引用了不同的数据库表,当编译此包时,该事务就获得了引用表的共享DDL锁。 
分析锁:ORACLE使用共享池存储分析与优化过的SQL语句及PL/SQL程序,使运行相同语句的应用速度更快。一个在共享池中缓存的对象获得它所引用数据库对象的分析锁。分析锁是一种独特的DDL锁类型,ORACLE使用它追踪共享池对象及它所引用数据库对象之间的依赖关系。当一个事务修改或删除了共享池持有分析锁的数据库对象时,ORACLE使共享池中的对象作废,下次在引用这条SQL/PLSQL语句时,ORACLE重新分析编译此语句。

2.oracle数据库在什么情况下会锁表
引起锁的情况很多,例如:
Select ... for update ;
Lock Table ;
外键约束;
Alter table ...
等等。。。

3.锁表后的解决办法
一般情况下,锁并不可怕,只有遇到死锁时比较麻烦。
select * from v$locked_object;
可以查到系统中被锁住的对象。
再和 select * from v$session 中连接,查出是锁标的session;
alter system kill session 'sid,serial' 即可
在ops下,更麻烦一点
需要查询的动态试图要加‘G’,例如gv$session
同时,在kill  session时需要找到改会话所在的实例,连接到正确的instance中kill才会成功

<详细步骤>
查询表的状况的对象:V$LOCK, V$LOCKED_OBJECT, V$SESSION, V$SQLAREA, V$PROCESS

  select * from v$locked_object

  select * from dba_objects

  方法:

  首先查看那些表被锁住了

  -----------------------------------------------------------------

  select b.owner, b.object_name, a.session_id, a.locked_mode

  from v$locked_object a, dba_objects b

  where b.object_id = a.object_id;

  -----------------------------------------------------------------

  select b.username, a.LOCKED_MODE, b.sid, b.serial#, logon_time

  from v$locked_object a, v$session b

  where a.session_id = b.sid

  order by b.logon_time;

  -----------------------------------------------------------------

  select b.sid,

  b.serial#,

  c.object_name,

  b.username,

  a.LOCKED_MODE,

  b.logon_time

  from v$locked_object a, v$session b, dba_objects c

  where a.session_id = b.sid

  and a.object_id = c.object_id

  order by b.logon_time;

  -----------------------------------------------------------------

  杀进程中的会话

  alter system kill session 'SID,SERIAL#';

  例如:

  alter system kill session '29,5497';

  ------------------------------------------------
数据库中其他知识补充:
ORACLE里锁有以下几种模式:
  0:none

  1:null 空

  2:Row-S 行共享(RS):共享表锁

  3:Row-X 行专用(RX):用于行的修改

  4:Share 共享锁(S):阻止其他DML操作

  5:S/Row-X 共享行专用(SRX):阻止其他事务操作

  6:exclusive 专用(X):独立访问使用

  数字越大锁级别越高, 影响的操作越多。

  一般的查询语句如select ... from ... ;是小于2的锁, 有时会在v$locked_object出现。

  select ... from ... for update; 是2的锁。

  当对话使用for update子串打开一个游标时,

  所有返回集中的数据行都将处于行级(Row-X)独占式锁定,

  其他对象只能查询这些数据行,不能进行update、delete或select...for update操作。

  insert / update / delete ... ; 是3的锁。

  没有commit之前插入同样的一条记录会没有反应,

  因为后一个3的锁会一直等待上一个3的锁, 我们必须释放掉上一个才能继续工作。

  创建索引的时候也会产生3,4级别的锁。

  locked_mode为2,3,4不影响DML(insert,delete,update,select)操作,

  但DDL(alter,drop等)操作会提示ora-00054错误。

  有主外键约束时 update / delete ... ; 可能会产生4,5的锁。

  DDL语句时是6的锁。



  SELECT S.SID SESSION_ID,

  S.USERNAME,

  s.SERIAL#,

  DECODE(LMODE,

  0,

  'None',

  1,

  'Null',

  2,

  'Row-S (SS)',

  3,

  'Row-X (SX)',

  4,

  'Share',

  5,

  'S/Row-X (SSX)',

  6,

  'Exclusive',

  TO_CHAR(LMODE)) MODE_HELD,

  DECODE(REQUEST,

  0,

  'None',

  1,

  'Null',

  2,

  'Row-S (SS)',

  3,

  'Row-X (SX)',

  4,

  'Share',

  5,

  'S/Row-X (SSX)',

  6,

  'Exclusive',

  TO_CHAR(REQUEST)) MODE_REQUESTED,

  O.OWNER || '.' || O.OBJECT_NAME || ' (' || O.OBJECT_TYPE || ')',

  S.TYPE LOCK_TYPE,

  L.ID1 LOCK_ID1,

  L.ID2 LOCK_ID2

  FROM V$LOCK L, SYS.DBA_OBJECTS O, V$SESSION S

  WHERE L.SID = S.SID

  AND L.ID1 = O.OBJECT_ID;

<!-- 正文结束 -->

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28906333/viewspace-1115545/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2013-05-21