您的位置:首页 > 数据库 > Oracle

DML锁(TX、TM锁)和DDL锁(排他、共享、可中断解析锁)基础

2016-10-17 21:26 363 查看

DML锁

DML锁用于确保一次只有一个人能修改一行,而且这时别人不能删除这个表。

1.TX锁

A row lock, also called a TX lock, is alock on a single row of table. A transaction acquires a row lock for each rowmodified by an INSERT, UPDATE, DELETE,MERGE, or SELECT ... FOR UPDATEstatement. The row lock exists until the transaction commits or rollsback.一个行锁,也被称为TX lock,是对于表中一行的一个锁。当对行进行INSERT, UPDATE, DELETE,MERGE, or SELECT ... FOR UPDATE等操作时事务需要获取一个TX锁。这个锁会持续到事务提交或者rollback。If a transaction obtains a lock for a row,then the transaction also acquires a lock for the table containing the row. Thetable lock prevents conflicting DDL operations that would override data changesin a current transaction.可以防止DDL操作覆盖当前事务的数据。
复制EMP和DEPT表模拟实验。
EODA@PROD1> set lines 13EODA@PROD1> column username format a15EODA@PROD1> set echo on;EODA@PROD1> create table dept as select * from scott.dept;Table created.EODA@PROD1> create table emp as select * from scott.emp;Table created.EODA@PROD1> alter table dept add constraint dept_pk primary key(deptno);Table altered.EODA@PROD1> alter table emp add constraint emp_pk primary key(empno);Table altered.EODA@PROD1> alter table emp add constraint emp_fk_dept foreign key (deptno) references dept(deptno);Table altered.EODA@PROD1> create index emp_deptno_idx on emp(deptno);Index created.
--在第一个会话中执行
EODA@PROD1> select username,2  	      v$lock.sid,3  	      trunc(id1/power(2,16)) rbs,4  	      bitand(id1,to_number('ffff','xxxx'))+0 slot,5  	      id2 seq,6  	      lmode,7  	      request8    from v$lock, v$session9    where v$lock.type = 'TX'10  	 and v$lock.sid = v$session.sid11  	 and v$session.username = USER;USERNAME	       SID	  RBS	    SLOT	SEQ	 LMODE	  REQUEST--------------- ---------- ---------- ---------- ---------- ---------- ----------EODA			35	   19	      32	588	     6		0EODA@PROD1> select XIDUSN, XIDSLOT, XIDSQN from v$transaction;XIDUSN    XIDSLOT	  XIDSQN---------- ---------- ----------19	   32	     588
V$LOCK lists the locks currently held bythe Oracle Database and outstanding requests for a lock or latch.V$LOCK常用列:Column   Datatype DescriptionADDR      RAW(4| 8)        Address of lockstate objectKADDR    RAW(4| 8)        Address of lockSID  NUMBER Identifier for session holding or acquiring thelock --持有锁的会话SIDTYPE        VARCHAR2(2)  --主要为TM和TX两种类型ID1  NUMBER Lock identifier #1 (depends on type)   --当lock type 为TM时,id1为DML-lockedobject的object_idID2  NUMBER Lock identifier #2 (depends on type)  --当lock type 为TX时,id1为usn+slot,而id2为seq。LMODE   NUMBER Lock mode in which the session holds the lock --大于0时表示当前会话以某种模式占有该锁,等于0时表示当前会话正在等待该锁资源,即表示该会话被阻塞。REQUEST NUMBER Lock mode in which theprocess requests thelockCTIME     NUMBER Time since current mode was grantedBLOCK     NUMBER Indicateswhether the lock in question is blocking otherprocesses.
Lock mode in which the session holds the lock:
0
 - none
1
 - null (NULL)
2
 - row-S (SS)
3
 - row-X (SX)
4
 - share (S)
5
 - S/Row-X (SSX)
6
 - exclusive (X)
上述实验结果查询v$lock表时,LMODE为6,REQUEST为0表明该事务拥有一个排它锁。
--在第二个会话中执行
EODA@PROD1> update emp set ename = upper(ename);14 rows updated.EODA@PROD1> update dept set deptno = deptno-10;  --会话被阻塞,数据库hang住了
--再次查询v$lock
EODA@PROD1> select username,2  	      v$lock.sid,3  	      trunc(id1/power(2,16)) rbs,4  	      bitand(id1,to_number('ffff','xxxx'))+0 slot,5  	      id2 seq,6  	      lmode,7  	      request8    from v$lock, v$session9    where v$lock.type = 'TX'10  	 and v$lock.sid = v$session.sid11  	 and v$session.username = USER;USERNAME	       SID	  RBS	    SLOT	SEQ	 LMODE	  REQUEST--------------- ---------- ---------- ---------- ---------- ---------- ----------EODA			35	   19	      32	588	     6		0EODA			45	   19	      32	588	     0		6EODA			45	   18	      27	583	     6		0EODA@PROD1> select XIDUSN, XIDSLOT, XIDSQN from v$transaction;XIDUSN    XIDSLOT	  XIDSQN---------- ---------- ----------19	   32	     58818	   27	     583
通过查询v$transaction得出此时开始了一个新的事务(18,27,583),SID为45的新会话在v$lock中有两行记录。首先拥有(18,27,583)排它锁其次在请求(19,32,588)即第一个会话的排它锁。
EODA@PROD1> col blocker format a15EODA@PROD1> col blockee format a15EODA@PROD1> select2  	     (select username from v$session where sid=a.sid) blocker,3  	      a.sid,4  	     ' is blocking ',5  	      (select username from v$session where sid=b.sid) blockee,6  		  b.sid7  	 from v$lock a, v$lock b8  	where a.block = 19  	  and b.request > 010  	  and a.id1 = b.id111  	  and a.id2 = b.id2;BLOCKER 	       SID 'ISBLOCKING'  BLOCKEE		SID--------------- ---------- ------------- --------------- ----------EODA			35  is blocking  EODA			 45
通过一个v$lock的自连接查询可以更明确看到哪个SID阻塞了哪个SID。
而如果提交了第一个事务,再次查询就可以看见请求不见了。
EODA@PROD1> commit;Commit complete.EODA@PROD1> select username,2  	      v$lock.sid,3  	      trunc(id1/power(2,16)) rbs,4  	      bitand(id1,to_number('ffff','xxxx'))+0 slot,5  	      id2 seq,6  	      lmode,7  	      request8    from v$lock, v$session9    where v$lock.type = 'TX'10  	 and v$lock.sid = v$session.sid11  	 and v$session.username = USER;USERNAME	       SID	  RBS	    SLOT	SEQ	 LMODE	  REQUEST--------------- ---------- ---------- ---------- ---------- ---------- ----------EODA			45	   18	      27	583	     6		0EODA@PROD1> select XIDUSN, XIDSLOT, XIDSQN from v$transaction;XIDUSN    XIDSLOT	  XIDSQN---------- ---------- ----------18	   27	     583
可以看到请求行已经不见了,因为另一个会话已经放弃了锁。

2.TM锁

TM锁用于确保在修改表的内容时,表的结构不会被改变。A table lock, also called a TM lock, isacquired by a transaction when a table is modified by an INSERT, UPDATE,DELETE, MERGE, SELECT with the FOR UPDATE clause, or LOCK TABLE statement. DMLoperations require table locks to reserve DML access to the tableon behalf ofa transaction and to prevent DDL operations that would conflict with thetransaction.一个表锁,也被称为TM锁,被用于一个事务中当表被通过INSERT, UPDATE, DELETE, MERGE, SELECT with theFOR UPDATE clause修改或者进行了LOCK TABLE操作。被用来防止DDL操作导致事务冲突影响了自身的事务。--模拟观察
EODA@PROD1> set echo onEODA@PROD1> create table t1 ( x int );Table created.EODA@PROD1> create table t2 ( x int );Table created.EODA@PROD1> insert into t1 values ( 1 );1 row created.EODA@PROD1> insert into t2 values ( 1 );1 row created.EODA@PROD1> col username form a15EODA@PROD1> select (select username2  		 from v$session3  		where sid = v$lock.sid) username,4  	      sid,5  	      id1,6  	      id2,7  	      lmode,8  	      request, block, v$lock.type9  	 from v$lock10  where sid = sys_context('userenv','sid');USERNAME	       SID	  ID1	     ID2      LMODE    REQUEST	    BLOCK TY--------------- ---------- ---------- ---------- ---------- ---------- ---------- --EODA			35	  100	       0	  4	     0		0 AEEODA			35	68045	       1	  3	     0		0 TOEODA			35	85694	       0	  3	     0		0 TMEODA			35	85695	       0	  3	     0		0 TMEODA			35     917523	     583	  6	     0		0 TXEODA@PROD1> column object_name form a15EODA@PROD1> select object_name, object_id from user_objects where object_name in ('T1','T2');OBJECT_NAME	 OBJECT_ID--------------- ----------T1		     85694T2		     85695
虽然每个事务只能得到一个TX锁,但是TM锁并不一样,修改了多少个对象,就能得多少个TM锁。这里TM锁的ID1列就是DML锁定对象的对象ID,所以很容易发现哪个对象持有这个锁。**关于TM锁还有另外一个有意思的地方,系统中允许的TM锁总数可以由你来进行配置,设置DML_LOCKS参数。DML_LOCKSProperty  DescriptionParameter type        IntegerDefault value   Derived: 4 * TRANSACTIONSModifiable        NoRange of values        20 to unlimited; a setting of 0 disables enqueuesBasic         NoOracleRAC       You must set this parameter for every instance, and all instances must have positive values or all must be 0.--如果该参数设置为0If you set the value of DML_LOCKS to 0,enqueues are disabled and performance is slightly increased. However, youshould be aware of the following restrictions when you set you DML_LOCKS to 0:You cannot use DROP TABLE, CREATE INDEX statements  --不能进行删表,创建索引操作EnterpriseManager cannot run on any instances for which DML_LOCKS is set to 0 --EM不能运行You cannot use explicit lock statements such as LOCK TABLE IN EXCLUSIVE MODE  --不能显示锁定事务在非常专业的应用比如RAC中,这一点很有用,可以减少实例内可能发生的协调次数。通过使用ALTER TABLE <> DISABLE TABLE LOCK命令还可以针对对象逐一禁用TM锁。

DDL锁

在DDL操作中会自动为对象加DDL锁,从而保护这些对象不会被其他会话所修改。在DDL语句执行期间会一直持有DDL锁,一旦操作执行完毕就会立即释放。排他DDL锁(exclusive DDL lock):这会防止其他会话得到他们自己的DDL锁或TM锁。这说明,在DDL操作期间可以查询一个表,但是无法以任何方式修改这个表。共享DDL锁(share DDL lock):这些锁会保护所引用的对象的结构,使之不会被其他会话修改,但是允许修改数据。可中断解析锁(breakable parse lock):这些锁允许一个对象向其他对象注册其依赖性。???--参考来源《Oracle编程艺术深入理解数据库体系结构(第三版)》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  事务 oracle DML锁 DDL锁