ITPub博客

首页 > Linux操作系统 > Linux操作系统 > DML操作引起的blocking(一)

DML操作引起的blocking(一)

原创 Linux操作系统 作者:realkid4 时间:2011-02-20 00:00:47 0 删除 编辑

 

Oracle两个同时进行的insert不会被阻塞..”

 

Oracle是目前支持并行操作处理最好的数据库系统。在开始提供商业化数据库产品的阶段,事务行锁和多版本一致读的特性就奠定了Oracle商业数据库领军的地位。这两个特性的最终目的就是提高数据库系统的并发操作能力。

 

并发操作可以最大限度的提升系统的整体性能,但是也必然引起资源的公用。无论在数据库系统,还是在操作系统等其他系统中,资源的共享与互斥必然回引入锁技术。过小的范围锁不能满足资源共享保护需求,过大的范围锁又会限制并行特性的发挥。

 

多版本一致读

 

Oracle中,一般性select读操作是不会阻塞其他dml操作的。同时,在进行dml操作的时候,也不会影响到select操作获取数据。举例来说:当一个会话session1进行数据表数据dml操作的时候,没有进行commit/rollback操作。另一个会话session2是可以进行select操作,获取的数据是session1进行修改之前的数据。

 

session1提交了事务之后,所有会话select的数据就是提交之后的数据集合。整个过程中,所有其他会话发出的select操作是不会因为session1的事务而被阻塞。

 

 

事务行级锁

 

事务行级锁是Oracle的另一个出色特性。当进行事务的时候,为了防止其他会话对数据进行修改,不同的数据库系统是采用不同的控制方法的。通常的做法有数据表级锁、页级锁等。但是这些类型锁都不免将锁定资源的范围扩大化。Oracle提供了事务行级锁,每个事务只会锁定该事务修改的数据行,不会影响到其他与事务无关的数据。一些资料中,将Oracle这个特性也叫行级锁,很多人理解为Oracle在每个数据行进行加锁,这实际上是不准确的。因为即使我们修改了多行,从Oracle的角度看,也只是加了一个锁,锁住了多行数据集而已。

 

 

那么,回到开篇的“Oracle两个同时进行的insert不会被阻塞..”,这种说法对吗?下面我们分别进行一系列的实验,来证明这种说法。

 

下面是环境准备。

 

SQL> conn scott/tiger@orcl;

已连接。

SQL> create table t (id number(10), name varchar2(20));

 

表已创建。

 

SQL> alter table t add constraint pk_t_id primary key (id); //确立主键

 

表已更改。

 

 

1、无关数据行插入

 

首先我们同时使用两个会话,进行无关数据行的插入。

 

//session1

SQL> conn scott/tiger@orcl;

已连接。

 

SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

       158

 

SQL> insert into t values (1,'ddd');

 

已创建 1 行。

 

 

首先,启动了一个会话(sid=158),下面开启另一个会话。

 

 

//session2

SQL*Plus: Release 10.2.0.1.0 - Production on 星期六 2月 19 20:15:16 2011

 

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

 

SQL> conn scott/tiger@orcl;

已连接。

SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

       141

 

 

SQL> insert into t values(2,'dkl');

 

已创建 1 行。

 

我们发现,启动两个会话,同时开启数据库事务,插入两条无关数据,不会发生阻塞。注意:我们强调的是无关数据,就是两条数据可以在数据表中提交并存。

 

此时,我们观察一下系统的锁视图情况。

 

 

//锁状态

SQL> select * from v$locked_object;

 

    XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID SESSION_ID ORACLE_USERNAME OS_USER_NAME   PROCESS  LOCKED_MODE

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

    4         45    870   53606  141 SCOTT IBM-VS2A1BHCNS0\ibm  772:3932               3

    3         19    842   53606  158 SCOTT IBM-VS2A1BHCNS0\ibm  636:1036               3

 

//object_id=53606对应数据表T

SQL> select * from dba_objects where object_id=53606;

OWNER                          OBJECT_NAME         

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

SCOTT                          T                   

 

//锁状态检查

SQL> select * from v$lock where sid in (141,158);

 

ADDR     KADDR           SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME  BLOCK

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

6BDC4074 6BDC408C        158 TM        53606          0          3          0        226  0

6BDC4138 6BDC4150        141 TM        53606          0          3          0        214  0

6BE185A8 6BE186C4        158 TX       196627        842          6          0        226  0

6BE29A54 6BE29B70        141 TX       262189        870          6          0        214  0

 

 

SQL> select sid, serial#, lockwait, sql_id, blocking_session_status,EVENT#, EVENT

  2  from v$session where sid in (141,158);

 

       SID    SERIAL# LOCKWAIT SQL_ID        BLOCKING_SESSION_STATUS     EVENT# EVENT

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

       141         47                        NO HOLDER                      256 SQL*Net message from client

158        122                        NO HOLDER                      256 SQL*Net message from client

 

 

 

额外说明:视图v$locked_object前三个数据列,xidusn为进行dml操作时候,使用undo段的编号,xidslot为段对象的slot编号,xidsqn为段对象的系列号。三个字段表示了对象在undo表空间上的对应位置。对应的xidsqn对应v$lock锁的id2属性。

 

 

 

v$lock视图的情况下,我们不难发现并行插入的过程。首先,两个会话在数据表T上加一个表级别(TM)的共享锁(LMODE=3)。LMODE=3是可以共享的,在数据表上加共享锁的目的就是防止在事务进行中,尝试对数据表结构进行一些修改。同时,在不同的数据行,发起事务锁(TX),模式为独占模式。分别排他锁住两个数据行。这两个会话事务结构之间不会发生阻塞情况。

 

 

那么,在这样的方式下,是不是不会发生blocking类型的阻塞?下面我们进行一些其他实验。

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

请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    7689963