[20130125]DML操作出现交集的情况.txt

[20130125]DML操作出现交集的情况.txt

昨天同事问了一个问题,如果DML操作出现交叉的情况下,oracle是如何处理的?

我自己还是建立一个测试例子来说明:

1.建立测试环境:

SQL> select * from v$version where rownum
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
CREATE TABLESPACE aaa DATAFILE 
  '/u01/app/oracle11g/oradata/test/aaa01.dbf' SIZE 10M AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED
LOGGING
PERMANENT
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT MANUAL
FLASHBACK ON;

--建立表空间mssm主要目的是演示可以重复,保持插入的数据顺序与显示的信息一致。

create table t tablespace aaa as select rownum id1 ,1 id2 ,'aaaa' name from dual connect by levelalter table t minimize records_per_block;
--这样限制每个数据块3条记录

insert into t     select rownum id1 ,2 id2 ,'bbbb' name from dual connect by level
insert into t     select rownum id1 ,3 id2 ,'cccc' name from dual connect by level
commit ;
SQL1> select rowid,a.* from t a;
ROWID                     ID1        ID2 NAME
------------------ ---------- ---------- --------------------------------------------------
AABBqUAALAAAACBAAA          1          1 aaaa
AABBqUAALAAAACBAAB          2          1 aaaa
AABBqUAALAAAACBAAC          3          1 aaaa
AABBqUAALAAAACCAAA          1          2 bbbb
AABBqUAALAAAACCAAB          2          2 bbbb
AABBqUAALAAAACCAAC          3          2 bbbb
AABBqUAALAAAACDAAA          1          3 cccc
AABBqUAALAAAACDAAB          2          3 cccc
AABBqUAALAAAACDAAC          3          3 cccc

9 rows selected.
--注意我表空间是mssm,显示的数据与插入的数据一致。
--从rowid也可以看出数据分布在3个块中。

2.开始测试:
--打开回话1,修改数据不提交:
SQL1> update t set name='3333' where id2=3;

SQL1> select dbms_transaction.local_transaction_id z10 from dual;
Z10
----------
7.31.9750

--打开回话2,修改数据不提交:
SQL2> update t set name='1111' where id1=1;

--这样第2个回话也会修改了id1=1,id2=3的行记录,出现阻塞,回话挂起。
--打开回话3执行如下:

SQL3> select addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec,status, start_time, start_scnb, start_scnw, ses_addr from v$transaction;
ADDR                 XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC STATUS           START_TIME           START_SCNB START_SCNW SES_ADDR
---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- -------------------- ---------- ---------- ----------------
00000000B5633B00          6         11      10614          3        211       5109         36 ACTIVE           01/25/13 08:45:31    3221927474          0 00000000BF192EF8
00000000B75BADE8          7         31       9750          3       3582       5076         16 ACTIVE           01/25/13 08:45:05    3221927242          0 00000000B51B7E98

--从显示可以看出,第2行信息与回话1的信息相符合。第1行自然与第2个回话有关。
--这个时候如果在第3个回话执行update t set name='xxxx' where id1=1 and id2=1;可行吗?会挂起吗?

SQL3> update t set name='xxxx' where id1=1 and id2=1;
--可以发现一样会挂起!

3.全部rollback,再做另外的测试:

--回话1执行如下,不提交:
SQL1> update t set name='1111' where id2=1;
SQL1> select dbms_transaction.local_transaction_id z10 from dual;
Z10
----------
9.20.10218

--回话2执行如下,修改数据不提交:
SQL2> update t set name='XXXX' where id1=1;

--这样第2个回话也会修改了id1=1,id2=1的行记录,出现阻塞,回话挂起。
--回话3执行如下:

SQL3> select addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec,status, start_time, start_scnb, start_scnw, ses_addr from v$transaction;
ADDR                 XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC STATUS           START_TIME           START_SCNB START_SCNW SES_ADDR
---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- -------------------- ---------- ---------- ----------------
00000000B75BADE8          9         20      10218          3       3099       5252          6 ACTIVE           01/25/13 09:02:37    3221927691          0 00000000B51B7E98

--从显示可以看出仅仅1行,信息与回话1的信息相符合.而没有第2行信息,
--这个时候如果在第3个回话执行update t set name='xxxx' where id1=1 and id2=3;可行吗?会挂起吗?从视图v$transaction一定不
--会出现阻塞。

SQL3> update t set name='yyyy' where id1=1 and id2=3;
1 row updated.

--确实可以!可以发现可以执行,并没有挂起。这次全部提交。
--提交按照如下顺序 回话3=>回话1=>回话2.

SQL1> select rowid,a.* from t a;
ROWID                     ID1        ID2 NAME
------------------ ---------- ---------- -------
AABBqUAALAAAACBAAA          1          1 XXXX
AABBqUAALAAAACBAAB          2          1 1111
AABBqUAALAAAACBAAC          3          1 1111
AABBqUAALAAAACCAAA          1          2 XXXX
AABBqUAALAAAACCAAB          2          2 bbbb
AABBqUAALAAAACCAAC          3          2 bbbb
AABBqUAALAAAACDAAA          1          3 XXXX
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AABBqUAALAAAACDAAB          2          3 cccc
AABBqUAALAAAACDAAC          3          3 cccc
9 rows selected.

--注意~线显示的信息:id1=1 id2=3的name='XXXX',而不是name='yyyy',
--这个也非常像我们应用系统中以前遇到的一个bug,一旦应用中出现阻塞,整个业务流程出现一些奇怪的问题。

总结:
1.可以说明oracle仅仅进入块中才知道行记录是否存在锁。
2.oracle遇到行记录没上锁,DML执行后,再上锁。遇到阻塞,回话挂起,等待解除。这样别的回话不能DML已经上锁的行记录。

时间: 2024-11-13 04:34:03

[20130125]DML操作出现交集的情况.txt的相关文章

[20130125]DML操作出现交集的情况[补充].txt

[20130125]DML操作出现交集的情况[补充].txt 昨天同事问了一个问题,如果DML操作出现交叉的情况下,oracle是如何处理的?对前面再做一些补充. http://space.itpub.net/267265/viewspace-753269 我自己还是建立一个测试例子来说明: 1.建立测试环境:SQL> select * from v$version where rownumBANNER-----------------------------------------------

Hive基本操作,DDL操作(创建表,修改表,显示命令),DML操作(Load Insert Select),Hive Join,Hive Shell参数(内置运算符、内置函数)等

1.  Hive基本操作 1.1  DDL操作 1.1.1    创建表 建表语法 CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name    [(col_name data_type[COMMENT col_comment], ...)] +    [COMMENT table_comment]    [PARTITIONED BY (col_namedata_type [COMMENT col_comment], ...)]    [CLUST

Oracle并行操作——并行DML操作

  对大部分的OLTP系统而言,并行DML(PDML)的应用场景不多.大多数的PDML操作集中在下面几个场景下:   ü        系统移植,从旧系统中导入原始数据和基础数据: ü        数据仓库系统Data Warehouse定期进行大批量原始数据导入和清洗: ü        借助一些专门的工具,如sql loader,进行数据海量导入:   本篇主要介绍并行DML操作的一些细节和注意方面.   1.环境准备   Oracle并行操作前提两个条件,其一是盈余的软硬件资源,其二是海

DDL,DML操作对结果缓存的影响

一 DDL 语句对结果缓存的影响. 清理实验环境,使用hint构造结果缓存,cache_id 为93qg9pxgyrhd35bxgp9ay1mvqw.yang@rac1>exec dbms_result_cache.flush(); PL/SQL 过程已成功完成. 已用时间:  00: 00: 00.00yang@rac1>set autotrace onyang@rac1>select /*+ result_cache */ object_type,count(*) from yang

SQL Server如何用触发器捕获DML操作的会话信息

需求背景        上周遇到了这样一个需求,维护人员发现一个表的数据经常被修改,由于历史原因:文档缺少:以及维护人员的经常变更,导致他们对系统也业务也不完全熟悉,他们也不完全清楚哪些系统和应用程序会对这个表的数据进行操作.现在他们想找出有哪些服务器,哪些应用程序会对这个表进行INSERT.UPDATE操作.那么问题来了,怎么去解决这个问题呢?   解决方案 由于数据库版本是标准版,我们选择了使用触发器来捕获进行DML操作的会话的相关信息,例如,Host_Name.Program_Name等

Sql Server之旅——第十站 看看DML操作对索引的影响

原文:Sql Server之旅--第十站 看看DML操作对索引的影响 我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕....   一:delete操作 现在我们已经知道,索引都是以B树的形式存在的,既然是B树,我们就要看看他们的叶子节点和分支结点,先准备点测试数据,如下图: CREATE TABLE Person(ID INT,NAME CHAR(200)) CREATE

SQL Server实现用触发器捕获DML操作的会话信息【实例】

需求背景 上周遇到了这样一个需求,维护人员发现一个表的数据经常被修改,由于历史原因:文档缺少:以及维护人员的经常变更,导致他们对系统也业务也不完全熟悉,他们也不完全清楚哪些系统和应用程序会对这个表的数据进行操作.现在他们想找出有哪些服务器,哪些应用程序会对这个表进行INSERT.UPDATE操作.那么问题来了,怎么去解决这个问题呢? 解决方案 由于数据库版本是标准版,我们选择了使用触发器来捕获进行DML操作的会话的相关信息,例如,Host_Name.Program_Name等 ,选择触发器是因为

Sql Server之旅——第十站 看看DML操作对索引的影响 

我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕.... 一:delete操作 现在我们已经知道,索引都是以B树的形式存在的,既然是B树,我们就要看看他们的叶子节点和分支结点,先准备点测试数据,如下图: CREATE TABLE Person(ID INT,NAME CHAR(200)) CREATE INDEX idx_Name ON Person(NAME) DECLAR

动态查询,动态生成cursor或者动态执行SQL的DML操作

定义PROCEDURE P1 ( P_Asset_Type IN varchar2,P_Asset_SubType IN varchar2,P_OrderIds IN varchar2). 需要根据传入参数动态查询,动态生成cursor或者动态执行SQL的DML操作. 1.简单的查询 SELECT   ABC from TableA where ORDER_ID IN ( P_OrderIds) : 2. 动态生成cursor 定义游标和变量: type   v_cursor   is   re