`
liwenshui322
  • 浏览: 519089 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

oracle DML锁介绍

阅读更多

      DML锁(DML Lock)用于确保一次只有一个人能修改某一行,而且你正在处理一个表时别人不能删除这个表。在你工作时,Oracle会透明程度不一地为你加这些锁。

      首先说第一种DML锁,事务锁。 事务发起第一个修改时会得到TX锁(事务锁),而且会一直持有这个锁,直至事务执行提交(COMMIT)或回滚(ROLLBACK)。

      TX锁用作一种排队机制,使得其他会话可以等待这个事务执行。事务中修改或通过SELECT FOR UPDATE选择的每一行都会“指向”该事务的一个相关TX锁。听上去好像开销很大,但实际上并非如此。要想知道这是为什么,需要从概念上对锁“居住”在哪里以及如何管理锁有所认识。在Oracle中,闩为数据的一个属性(第10章会给出Oracle块格式的一个概述)。Oracle并 没有一个传统的锁管理器,不会用锁管理器为系统中锁定的每一行维护一个长长的列表。不过,其他的许多数据库却是这样做的,因为对于这些数据库来说,锁是一 种稀有资源,需要对锁的使用进行监视。使用的锁越多,系统要管理的方面就越多,所以在这些系统中,如果使用了“太多的”锁就会有问题。

      oracle中的锁定过程如下:

      (1) 找到想锁定的那一行的地址。

      (2) 到达那一行。

      (3) 锁定这一行(如果这一行已经锁定,则等待锁住它的事务结束,除非使用了NOWAIT选项)。

      由于闩为数据的一个属性,Oracle不需要传统的锁管理器。事务只是找到数据[5],如果数据还没有被锁定,则对其锁定。有意思的是,找到数据时,它可能看上去被锁住了,但实际上并非如此。在Oracle中对数据行锁定时,行指向事务ID的一个副本,事务ID存储在包含数据的块中,释放锁时,事务ID却会保留下来。这个事务ID是事务所独有的,表示了回滚段号、槽和序列号。事务ID留在包含数据行的块上,可以告诉其他会话:你“拥有”这个数据(并非块上的所有数据都是你的,只是你修改的那一行“归你所有”)。另一个会话到来时,它会看到锁ID,由于锁ID表示一个事务,所以可以很快地查看持有这个锁的事务是否还是活动的。如果锁不活动,则允许会话访问这个数据。如果锁还是活动的,会话就会要求一旦释放锁就得到通知。因此,这就有了一个排队机制:请求锁的会话会排队,等待目前拥有锁的事务执行,然后得到数据。

      以下是一个小例子,展示了这到底是怎么回事,这里使用了3个V$ 表:

      1. V$TRANSACTION,对应每个活动事务都包含一个条目。

      2. V$SESSION,显示已经登录的会话。

      3. V$LOCK,对应持有所有enqueue队列锁以及正在等待锁的会话,都分别包含一个条目。这并不是说,对于表中被会话锁定的每一行,这个视图中就有相应的一行。你不会看到这种情况。如前所述,不存在行级锁的一个主列表。如果某个会话将EMP表中的一行锁定,V$LOCK视图中就有对应这个会话的一行来指示这一事实。如果一个会话锁定了EMP表中的数百万行,V$LOCK视图中对应这个会话还是只有一行。这个视图显示了各个会话有哪些队列锁。

      首先启动一个事务(如果你没有DEPT表的一个副本,只需使用CREATE TABLE AS SELECT来建立一个副本):

 ops$tkyte@ORA10G update dept set deptno = deptno+10;

4 rows updated.

下面来看看此时系统的状态。这个例子假设是一个单用户系统;否则,在V$TRANS ACTION中可以看到多行。即使在一个单用户的系统中,如果看到V$TRANSACTION中有多行也不要奇怪,因为许多后台Oracle进程可能也会执行事务。

ops$tkyte@ORA10G> 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 request

8 from v$lock, v$session

9 where v$lock.type = 'TX'

10 and v$lock.sid = v$session.sid

11 and v$session.username = USER;

USERNAME SID RBS SLOT SEQ LMODE REQUEST --------- ---- --- ---- ------ ----- ------- OPS$TKYTE 145 4 12 16582 6 0 ops$tkyte@ORA10G> select XIDUSN, XIDSLOT, XIDSQN

2 from v$transaction;

XIDUSN XIDSLOT XIDSQN

---------- ---------- ---------- 4 12 16582

      这里有几点很有意思:

1. $LOCK表中的LMODE为6,REQUEST为0。如果在Oracle Server Reference手册中查看V$LOCK表的定义,会发现LMODE=6是一个排他锁。请求(REQUEST)值为0则意味着你没有发出请求;也就是说,你拥有这个锁。

2. 这个表中只有一行。V$LOCK表更应算是一个队列表而不是一个锁表。许多人都认为V$LOCK中会有4行,因为我们锁定了4行。不过,你要记住,Oracle不会在任何地方存储行级锁的列表(也就是说,不会为每一个被锁定的行维护一个主列表)。要查看某一行是否被锁定,必须直接找到这一行[6]。

3. RBS、SLOT和SEQ值与V$TRANSACTION信息匹配。这就是我的事ID。       下面使用同样的用户名启动另一个会话,更新EMP中的某些行,并希望试图更新DEPT:

 ops$tkyte@ORA10G> update emp set ename = upper(ename);

14 rows updated.

ops$tkyte@ORA10G> update dept set deptno = deptno-10;

现在这个会话会阻塞。如果再次运行V$查询,可以看到下面的结果: ops$tkyte@ORA10G> 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 request

8 from v$lock, v$session

 9 where v$lock.type = 'TX'

 10 and v$lock.sid = v$session.sid

11 and v$session.username = USER;

USERNAME SID RBS SLOT SEQ LMODE REQUEST --------- ---- --- ---- ------ ----- ------- OPS$TKYTE

144 4 12 16582 0 6 OPS$TKYTE

144 5 34 1759 6 0 OPS$TKYTE

145 4 12 16582 6 0

ops$tkyte@ORA10G>

select XIDUSN, XIDSLOT, XIDSQN

2 from v$transaction;

XIDUSN XIDSLOT XIDSQN ---------- ---------- ---------- 5 34 1759 4 12 16582

这里可以看到开始了一个新的事务,事务ID是(5,34,1759)。这一次,这个新会话(SID=144)在V$LOCK中有两行。其中一行表示它所拥有的锁(LMODE=6)。另外还有一行,显示了一个值为6的REQUEST。这是一个对排他锁的请求。有意思的是,这个请求行的RBS/SLOT/SEQ值正是锁持有者的事务ID。SID=145的事务阻塞了SID=144的事务。只需执行V$LOCK的一个自联结,就可以更明确地看出这一点:

ops$tkyte@ORA10G> select

 2 (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.sid

7 from v$lock a, v$lock b

8 where a.block = 1

9 and b.request > 0

10 and a.id1 = b.id1

11 and a.id2 = b.id2;

BLOCKER SID 'ISBLOCKING' BLOCKEE SID --------- ---- ------------- --------- ---- OPS$TKYTE 145 is blocking OPS$TKYTE 144

 现在,如果提交原来的事务(SID=145),并重新运行锁查询,可以看到请求行不见了: ops$tkyte@ORA10G> 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 request

8 from v$lock, v$session

9 where v$lock.type = 'TX'

10 and v$lock.sid = v$session.sid

11 and v$session.username = USER;

USERNAME SID RBS SLOT SEQ LMODE REQUEST --------- ---- --- ---- ------ ----- ------- OPS$TKYTE 144 5 34 1759 6 0

 ops$tkyte@ORA10G> select XIDUSN, XIDSLOT, XIDSQN

2 from v$transaction;

XIDUSN XIDSLOT XIDSQN ---------- ---------- ---------- 5 34 1759

另一个会话一旦放弃锁,请求行就会消失。这个请求行就是排队机制。一旦事务执行,数据库会唤醒被阻塞的会话。当然,利用各种GUI工具肯定能得到更“好看”的显示,但是,必要时对你要查看的表有所了解还是非常有用的。

 

分享到:
评论

相关推荐

    oracle锁机制探讨

    在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁(用来保证表的结构不被用户修改),TX锁称为事务锁或行级锁。当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统...

    Oracle数据库的锁类型

    本文将深入探讨Oracle数据库中的锁类型,尤其是DML锁,以及它们是如何在并发环境中维护数据完整性的。 #### 二、Oracle数据库锁类型概览 Oracle数据库的锁类型大致可以分为三类:DML锁、DDL锁和内部锁与闩锁。DML...

    oracle数据库锁使用

    在Oracle中,锁主要分为两类:数据锁(DML锁)和字典锁。字典锁主要用于内部管理,特别是语法分析和DDL操作,用户无法直接控制。而数据锁则是我们关注的重点,它们涉及到实际的数据操作,包括对数据的读取和修改。 ...

    对于Oracle锁的一些理论总结

    本文主要探讨Oracle的锁理论,特别是DML锁,即数据操纵语言锁。 首先,锁的基本概念是用于控制共享资源的并发访问。在Oracle中,锁分为三类:DML锁(用于保护数据完整性)、DDL锁(保护数据库对象结构)以及内部锁...

    Oracle的锁机制

    根据保护的对象,Oracle的锁分为内部锁、闩、DDL锁和DML锁。内部锁和闩是系统内部管理的,用于保护数据库的内部结构。DDL锁保护数据库对象的结构,如表和索引的定义,自动在执行SQL定义语句时添加。DML锁则直接作用...

    Oracle的锁内幕解惑

    本文旨在深入探讨Oracle锁机制的内部原理,特别是针对DML锁、DDL锁以及Latch等锁机制进行详细解析,帮助DBA更好地理解和应对实际工作中遇到的各种锁问题。 #### 二、Oracle锁机制概览 Oracle的锁机制可以大致分为...

    Oracle 锁机制问题详解

    本文将详细介绍 Oracle 中的锁机制原理及其解锁方法。 #### 二、锁机制的重要性 在任何多用户数据库应用中,最终都会出现两个或更多用户希望同时处理相同记录的情况。这种情况在逻辑上是不可能的,并且数据库必须...

    oracle锁表及解锁

    表级锁通常用于DML操作或DDL操作,而行级锁则是在执行更新、插入或删除等操作时自动产生的。 #### 检查锁定情况 要检查Oracle数据库中的锁状态,可以使用以下查询语句: ```sql SELECT /*+RULE*/ s.username, ...

    浅谈ORACLE数据库锁的类型与机制.pdf

    Oracle 数据库锁可以分为五大类:DML 锁、DDL 锁、内部锁、分布式锁和 PCM 锁。 1. DML 锁(Data Locks):用于保护数据的完整性,防止多个用户同时访问同一数据块。 DML 锁可以分为两种: fixed lock 和 ...

    oracle常见的锁查询和处理

    RX锁在执行DML操作时自动应用,允许其他事务修改表中其他行,但不允许添加X锁。RS锁通常由`SELECT ... FROM ... FOR UPDATE`语句产生,用于锁定查询到的行,防止其他用户修改。S锁允许共享读取,不允许修改。SX锁...

    ORACLE锁深入分析

    进一步细分,Oracle的锁可以分为DML锁、DDL锁和内部锁与闩。DML锁用于保护数据的完整性,包括TM锁(表级锁)和TX锁(事务锁或行级锁)。TM锁在执行DML语句时自动申请,对整个表进行锁定,分为SS、SX、S、X四种模式。...

    Oracle数据库锁的研究.pdf

    - DML锁(Data Manipulation Language Locks):用于数据操作,包括行级锁(TX锁)和表级锁(TM锁)。行级锁在事务对数据行进行修改时自动获取,如INSERT、UPDATE、DELETE和SELECT...FOR UPDATE语句会引发行级锁。...

    ORACLE关于锁和V$LOCK的分析.docx

    当 Oracle 执行 DML 语句时,系统自动在所要操作的表上申请 TM 类型的锁。当 TM 锁获得后,系统再自动申请 TX 类型的锁,并将实际锁定的数据行的锁标志位进行置位。 在 V$LOCK 视图中,LMODE 列用于表示锁的模式。...

    数据库锁学习文档

    在Oracle数据库中,锁进一步细分为DML锁(数据锁)和DDL锁(字典锁)。DML锁用于确保数据完整性,而DDL锁则用于保护数据库对象的结构。此外,还有内部锁,主要用于数据库内部结构的保护,例如Latch,这是一种轻量级...

    oracle锁讲解笔记

    Oracle中的锁主要分为三类:DML锁、DDL锁和内部锁(LATCH)。DML锁又细分为表级锁(TM)和行级锁(TX)。 - **表级锁(TM)**:用于保护表级别的操作,防止DDL语句的执行。 - **行级锁(TX)**:用于保护行级别的...

Global site tag (gtag.js) - Google Analytics