ITPub博客

首页 > 数据库 > Oracle > Lock

Lock

原创 Oracle 作者:diashad 时间:2015-01-05 10:43:27 0 删除 编辑


ORACLE锁具体分为以下几类:


1.按用户与系统划分,可以分为自动锁与显示锁 
自动锁:当进行一项数据库操作时,缺省情况下,系统自动为此数据库操作获得所有有必要的锁。 
显示锁:某些情况下,需要用户显示的锁定数据库操作要用到的数据,才能使数据库操作执行得更好,显示锁是用户为数据库对象设定的。 


2.按锁级别划分,可分为共享锁与排它锁 
共享锁:共享锁使一个事务对特定数据库资源进行共享访问——另一事务也可对此资源进行访问(增删改吗?DDL是不是被禁止?)或获得相同共享锁。共享锁为事务提供高并发性,但如拙劣的事务设计+共享锁容易造成死锁或数据更新丢失。 
排它锁:事务设置排它锁后,该事务单独获得此资源,另一事务不能在此事务提交之前获得相同对象的共享锁或排它锁。 


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


死锁只能使用SQL下:alter system kill session "sid,serial#";或者使用相关操作系统kill进程的命令,如UNIX下kill -9 sid,或者使用其它工具杀掉死锁进程。 


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

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的锁。 


4.内部闩锁 
内部闩锁:这是ORACLE中的一种特殊锁,用于顺序访问内部系统结构。当事务需向缓冲区写入信息时,为了使用此块内存区域,ORACLE首先必须取得这块内存区域的闩锁,才能向此块内存写入信息。  

TM,锁表结构
TX,锁数据,itl(insert一般不会受影响,因为当前块的itl不足时,会选择下一个块来插入)
一般情况下TX必带TM,特殊:
a. 使用savepoint/远程表
b. disable table lock(alter table apps.tv disable table lock;)
c. DML_LOCKS设置为0(DML_LOCKS参数设置为0
d. 分布式事务(远程表)


锁主要是为了解决用户的并发操作而设计。有了锁后,操作一个对象,必须先要获得对象上的锁。
没有获得就无法操作。在操作时,如果没有回滚或提交,锁不会释放。


锁分类:
共享锁、排它锁。


行锁、表锁、死锁。




查看锁对象:
SQL> select OBJECT_ID,SESSION_ID,ORACLE_USERNAME,PROCESS,LOCKED_MODE 
from v$locked_object;

查看鎖表的進程
select sess.sid, 
    sess.serial#, 
    lo.oracle_username, 
    lo.os_user_name, 
    ao.object_name, 
    lo.locked_mode ,SESS.SQL_ID
    from v$locked_object lo, 
    dba_objects ao, 
    v$session sess 
where ao.object_id = lo.object_id and lo.session_id = sess.sid; 



锁的模式:
0: none
1: NULL # 可以某些情况下,如分布式数据库的查询会产生此锁
2: 行级共享锁(SS) # 表结构共享+加上部分数据共享.虽然有人说,ORACLE里,数据没有S状态,但我还是愿意这样理解:
# 第1个S代表表结构共享,第2个代表表里的数据共享. 你可以想象一下,当往子表里增加纪录时,主表的相关主键是不是得处于共享模式.


3: 行级独点锁(SX) # 用于DML操作,第1个S代表表结构共享,第2个代表表里被操作的数据独占
4: 共享锁(S) # S, 代表表结构+表里的数据都是处于共享模式.当对表创建索引时,在创建期间,表处于这种模式
5: 共享行级独占锁(SSX) #  SRX=S(4)+SX(3)
6: 独占锁(排它锁)(X) #  X, 删除表是会用上


加锁:
自动加:操作相关操作时会自动加
 
手动加:
lock table table_name in mode;
SQL> select * from emp for update;


解锁:
rollback;
commit;

辟免因锁影响性能:
及时提交和回滚。

lock 的相关视图
v$lock
v$lock_object
dba_dml_locks
dba_ddl_locks
dba_waiter


---------------------------------------------------------------------------
Most Common Lock Types:
---------------------------------------------------------------------------
 TYPE  Name ID1                     ID2
 ~~~~  ~~~~ ~~~                     ~~~
 TX    Transaction Decimal RBS & slot Decimal WRAP number
(0xRRRRSSSS  RRRR = RBS number, SSSS = slot )
A TX lock is requested in eXclusive mode if we are waiting on a ROW. 
A SHARE mode request implies we are waiting some other resource held
by the TX (Eg: waiting for an ITL entry)

 TM Table Locks Object id of table. Always 0.
 TS Temp Segment TS# Relative DBA
 ST Space Transaction Only ONE enqueue.
 UL   User Locks


当 v$lock.type=TM 时, ID1=57276: 锁定的对象的 object_id , ID2=0
  select * from dba_objects a where a.object_id = '57276' --object_name = 'TEST'


当 v$lock.type=TX 时, ID1: v$transaction.XIDUSN和v$transaction.XIDSLOT(ID1的高16位为XIDUSN,低16位为XIDSLOT)
# 该事务所占用的回滚段号与该事务在该回滚段的事务表(Transaction table)中所占用的槽号(slot number,可理解为记录号)。其组成形式为: 0xRRRRSSSS ( RRRR = RBS number, SSSS = slot )。
ID2: v$transaction.XIDSQN 
# 以十进制数值表示环绕(wrap)次数,即该槽(slot)被重用的次数;
  
SQL> SELECT s.XIDUSN,s.XIDSLOT, s.XIDSQN FROM v$transaction s;


XIDUSN    XIDSLOT  XIDSQN
---------- ---------- ----------
2   45    3585
 
ID1 转换 v$transaction.XIDUSN和v$transaction.XIDSLOT
SQL> select trunc(131117/power(2,16)) xidusn, bitand(131117,to_number('ffff','xxxx'))+0 xidslot from dual;


XIDUSN    XIDSLOT
---------- ----------
2   45
 
event 10704

[oracle@10g ~]$ oerr ora 10704
10704, 00000, "Print out information about what enqueues are being obtained"
// *Cause:  When enabled, prints out arguments to calls to ksqcmi and
//          ksqlrl and the return values.
// *Action: Level indicates details:
//   Level: 1-4: print out basic info for ksqlrl, ksqcmi
//          5-9: also print out stuff in callbacks:  ksqlac, ksqlop
//          10+: also print out time for each line




alter session set events '10704 trace name context forever, level 12';
select count(*) from scott.emp;
alter session set events '10704 trace name context off';


SQL> oradebug setmypid;
Statement processed.
SQL> oradebug event 10704 trace name context forever,level 10;
Statement processed.
SQL> lock  table tm in share mode;
Table(s) Locked.
SQL> oradebug tracefile_name;
/s01/admin/G10R2/udump/g10r2_ora_28400.trc

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

下一篇: latch
请登录后发表评论 登录
全部评论

注册时间:2011-08-08

  • 博文量
    86
  • 访问量
    472942