[转帖]DML操作引起的blocking(一)_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3834 | 回复: 0   主题: [转帖]DML操作引起的blocking(一)        下一篇 
kim
注册用户
等级:中校
经验:1729
发帖:222
精华:0
注册:2011-7-21
状态:离线
发送短消息息给kim 加好友    发送短消息息给kim 发消息
发表于: IP:您无权察看 2011-9-15 10:53:17 | [全部帖] [楼主帖] 楼主

“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类型的阻塞?下面我们进行一些其他实验。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论