Oracle Lock(Enqueues)
转载:http://www.cnblogs.com/Richardzhu/articles/2796540.html
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
在数据库中有两种基本的锁类型:排他锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排他锁时,其他的事务不能对它读取和修改;加了共享锁的数据对象可以被其他事务读取,但不能修改。
根据保护对象的不同,Oracle数据库锁可以分为以下几大类:
(1). DML lock (data locks,数据锁):用于保护数据的完整性;
(2). DDL lock(dictionary locks,字典锁):用于保护数据库对象的结构(例如表、视图、索引的结构定义);
(3). Internal locks和latches(内部锁与闩):保护内部数据库结构;
(4). Distributed locks(分布式锁):用于OPS(并行服务器)中;
(5). PCM locks (并行高速缓存管理锁):用于OPS(并行服务器)中。
在Oracle中最主要的锁是DML(也可称为data locks,数据锁)锁。DML锁的目的在于保证并发情况下的数据完整性。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。
Oracle TM锁的类型
锁模式 |
锁的描述 | 含义 | 锁定表的SQL |
0 | None | ||
1 | Null | 空,本模式是oracle预留模式 | |
2 | Row Share(RS)又叫(SS) |
行级共享锁,是限制最少的TM锁,可以提供最高程度的并发性,其他会话可以对锁定的表进行任何类型的DML操作,还可以与其他会话锁并存。 |
Lock table t in row share mode; |
3 | Row Exlusive Table Lock(RX)又叫(SX) | 行级排他锁,通常已经有事务在修改或者select...for update修改结果集。允许其他事务对锁定的表进行select、insert、update、delete或lock table 同时锁定一张表 | Lock table t in exclusive mode; |
4 | Share Table Lock(S) | 共享锁,其他事务可以查询锁定的表但不能修改,只允许当前事务修改,但可以多个事务持有它。 | Lock table t in share mode; |
5 | Share Row Exclusive Table Lock (SRX)又叫SSX | 共享行级排他锁,同一时间只允许一个事务持有和修改锁定的表,其他事务可以查询但不能修改。 | Lock table t in share row exclusive mode; |
6 | Exclusive Table Lock(X) | 排他锁,是限制最高的TM锁,禁止其他事务执行任何类型的DML语句或者锁表,一个表一般只能一个6号锁 。 | Lock table t in exclusive mode; |
1.行级共享锁(lmode=2,Row Share Table Lock,RS)
加锁语法:Lock Table TableName In Row Share Mode;
一个行级锁(有时称为Subshare Table Lock,简称,子共享锁)需要该事务在被锁定行的表上用update的形式加锁。当有下面语句被执行的时候行级锁自动加在操作的表上。
Select...from tablename...for update of ...;
允许的操作:行级共享锁由一个事务控制,允许其它事务查询、插入、更新、删除或同时在同一张表上锁定行。因此其它事务可以同时在同一张表上得到行级锁、共享行级排他锁、行级排他锁、排他锁。
禁止的操作:拥有行级锁的事务不允许其它事务执行排他锁,即:
Lock Table TableName In Exclusive Mode;
2.行级排他锁(lmode=3,Row Exclusive Table Lock,RX)
加锁语法:LOCK TABLE TableName IN ROW EXCLUSIVE MODE;
行级排他锁(亦称为Subexclusive Table Lock,简称SX,子排他锁)通常需要事务拥有的锁在表上被更新一行或多行。当有下面语句被执行的时候行级排他锁被加在操作的表上。
INSERT INTO TableName...;
UPDATE TableName...;
DELETE FROM TableName...;
LOCK TABLE TableName IN ROW EXCLUSIVE MODE;
行级排他锁比行级锁稍微多一些限制。
允许的操作:行级排他锁由一个事务拥有允许其它事务执行查询、修改、插入、删除或同时在同一张表上锁定行。只有行级排他锁的事务允许其它事务在同一张表上同时得到共享锁和行级排他锁。
禁止的操作:行级排他锁由一个事务拥有防止其它事务手动锁定表来排除其它事务的读写权限。因此,其它事务不允许在同一张表上使用以下的语句来执行行锁事务。
LOCK TABLE table IN SHARE MODE;
LOCK TABLE table IN SHARE EXCLUSIVE MODE;
LOCK TABLE table IN EXCLUSIVE MODE;
3.共享锁(lmode=4,Share Table Lock,S)
加锁语法:Lock Table TableName In Share Mode;
允许的操作:一个共享锁由一个事务控制,仅允许其它事务查询被锁定的表。一个有效的共享锁明确地有Select..for update 形式锁定行,或执行Lock Table TableName In Share Mode语法锁定整个表,不允许被其它事务更新。
禁止的操作:一个共享锁由一个事务来控制,防止其它事务更新该表或执行下面的语句:
Lock Table Tablename In Share Row Exclusive Mode;
Lock Table Tablename In row Exclusive Mode;
4.共享行级排他锁(lmode=5,Share Row Exclusive Table Lock,SRX)
共享行级排他锁有时也称共享子排他锁(Share Subexclusive Table Lock,SSX),它比共享锁有更多限制。定义共享行级排他锁的语法为:
LOCK TABLE TableName IN SHARE ROW EXCLUSIVE MODE;
允许的操作:仅允许一个事务在某一时刻得到的行级排他锁。拥有行级排他锁事务允许其它事务在被锁定的表上执行查询或使用Select...From TableName For Update...来准确的锁定行而不能更新行。
禁止的操作:拥有行级排他锁的事务不允许其它事务有除共享锁外的其它形式的锁加在同一张表上或更新该表。即下面的语句是不被允许的:
LOCK TABLE TableName IN SHARE MODE;
LOCK TABLE TableName IN SHARE ROW EXCLUSIVE MODE;
LOCK TABLE TableName IN ROW EXCLUSIVE MODE;
LOCK TABLE TableName IN EXCLUSIVE MODE;
5.排他锁(lmode=6)
排他锁是在锁机制中限制最多的一种类型,允许加排他锁的事务独自控制对表的写权限。
加锁语法:Lock Table Tablename In Exclusive Mode;
允许的操作:在一个表中只能有一个事务对该表实行排他锁,排他锁仅允许其它事务查询该表。
禁止的操作:拥有排他锁的事务禁止其它事务执行其它DML类型的语句或在该表上加任何其它类型的锁。
关于锁的一些实验:
1.分别模拟insert,update和delete造成阻塞的示例,并对v$lock中的相应的信息进行说明,给出SQL演示。
1.1、该实验中将使用的两个session:
1 SQL> select sid from v$mystat where rownum=1;
2
3 SID
4 ----------
5 1
1 SQL> select sid from v$mystat where rownum=1;
2
3 SID
4 ----------
5 48
使用到的一张表:
1 SQL> create table txt (id int primary key,name varchar2(10));
2
3 Table created.
4
5 SQL> desc txt;
6 Name Null? Type
7 ------------------ -------- ------------------------
8 ID NOT NULL NUMBER(38)
9 NAME VARCHAR2(10)
1.2、模拟insert造成的阻塞
在Session 1中插入一个语句:
1 SQL> insert into txt values (1,'aa');
2
3 1 row created.
此时Session 1还没有commit,但是Session 48中插入下面语句:
使用下面的语句查询得到:
1 SQL> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM') order by 1,2;
2
3 SID TY ID1 ID2 LMODE REQUEST BLOCK
4 ---------- -- ---------- ---------- ---------- ---------- ----------
5 1 TM 73545 0 3 0 0
6 1 TX 589837 745 6 0 1
7 48 TM 73545 0 3 0 0
8 48 TX 524309 964 6 0 0
9 48 TX 589837 745 0 4 0
从上图可以看到sid=1的BLOCK=1表示这个会话正在阻塞其他的会话,LMODE=6表示锁的级别是6,在sid=48中REQUEST=4表示当前会话正在等待一个LMODE=4的锁,意思是,这个会话正在被阻塞。
1.3、模拟update造成的阻塞
我们先查询一下表txt的内容:
1 SQL> select * from txt;
2
3 ID NAME
4 ---------- ----------
5 1 aa
在Session 1中更改这一行:
1 SQL> update txt set name='zz' where id=1;
2
3 1 row updated.
此时Session 1不执行commit,在Session 48中也去更改该行:
使用下面语句查询得:
1 SQL> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM') order by 1,2;
2
3 SID TY ID1 ID2 LMODE REQUEST BLOCK
4 ---------- -- ---------- ---------- ---------- ---------- ----------
5 1 TM 73545 0 3 0 0
6 1 TX 589841 745 6 0 1
7 48 TM 73545 0 3 0 0
8 48 TX 589841 745 0 6 0
此处不做说明,情况与insert大体类似。
1.4、模拟delete造成的阻塞
在Session 1中执行delete语句:
1 SQL> delete txt;
2
3 1 row deleted.
此时Session 48也执行delete语句:
使用下面语句查询得:
1 SQL> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM') order by 1,2;
2
3 SID TY ID1 ID2 LMODE REQUEST BLOCK
4 ---------- -- ---------- ---------- ---------- ---------- ----------
5 1 TM 73545 0 3 0 0
6 1 TX 458783 613 6 0 1
7 48 TM 73545 0 3 0 0
8 48 TX 458783 613 0 6 0
1.5、对v$lock中的信息说明:
1 SQL> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM') order by 1,2;
2
3 SID TY ID1 ID2 LMODE REQUEST BLOCK
4 ---------- -- ---------- ---------- ---------- ---------- ----------
5 1 TM 73545 0 3 0 0
6 1 TX 458783 613 6 0 1
7 48 TM 73545 0 3 0 0
8 48 TX 458783 613 0 6 0
其中:
SID:表示持有锁的会话信息
TYPE:表示锁的类型,值包括TM和TX等。
ID1:表示所的对象标识
ID2:ID1+ID2定位回滚段上的一个地址(即修改之前数据镜像地址)
LMODE:锁模式
REQUEST:申请锁的模式
BLOCK:A value of either 0 or 1, depending on whether or not the lock in question is the blocker
2.模拟RI锁定导致阻塞的场景,并分析v$lock相应的锁定信息,给出SQL演示。
该实验将创建两张新表:
1 SQL> create table tab1 (id int primary key,name varchar2(10));
2
3 Table created.
4
5 SQL> create table tab2 (id references tab1(id),num varchar2(10));
6
7 Table created.
2.1、在Session 1中对表tab1插入一条记录:
1 SQL> insert into tab1 values(1,'aa');
2
3 1 row created.
4
5 SQL> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM') order by 1,2;
6
7 SID TY ID1 ID2 LMODE REQUEST BLOCK
8 ---------- -- ---------- ---------- ---------- ---------- ----------
9 1 TM 73547 0 3 0 0
10 1 TM 73549 0 3 0 0
11 1 TX 327703 784 6 0 0
12
13 SQL> select object_name from dba_objects where object_id in (73547,73549);
14
15 OBJECT_NAME
16 --------------------------------------------------------------------------------
17 TAB1
18 TAB2
从上图可以看出,当在主表执行insert语句的时候,会给主表和从表都加上lmode=3的锁,这时在Session 48中对表tab2插入一条记录:
1 SQL> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM') order by 1,2;
2
3 SID TY ID1 ID2 LMODE REQUEST BLOCK
4 ---------- -- ---------- ---------- ---------- ---------- ----------
5 1 TM 73547 0 3 0 0
6 1 TM 73549 0 3 0 0
7 1 TX 327703 784 6 0 1
8 48 TM 73549 0 3 0 0
9 48 TM 73547 0 3 0 0
10 48 TX 589851 746 6 0 0
11 48 TX 327703 784 0 4 0
12
13 7 rows selected.
这时就会造成阻塞,而且Session 48会申请一个lmode=4的锁。
2.2、在Session 1中在表tab2插入一条记录,但之前先看一下tab1是表的内容:
1 SQL> select * from tab1;
2
3 ID NAME
4 ---------- ----------
5 1 aa
6
7 SQL> insert into tab2 values (2,'bb');
8 insert into tab2 values (2,'bb')
9 *
10 ERROR at line 1:
11 ORA-02291: integrity constraint (JACK.SYS_C0010811) violated - parent key not
12 found
直接给从表插入记录,如果主表没有的话会报错违反引用完整性约束,没有主表依据。
2.3、在Session 1中对表tab执行delete操作:
1 SQL> delete from tab2;
2
3 1 row deleted.
4
5 SQL> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM') order by 1,2;
6
7 SID TY ID1 ID2 LMODE REQUEST BLOCK
8 ---------- -- ---------- ---------- ---------- ---------- ----------
9 1 TM 73547 0 3 0 0
10 1 TM 73549 0 3 0 0
11 1 TX 131085 737 6 0 0
12
13 SQL> select object_name from dba_objects where object_id in (73547,73549);
14
15 OBJECT_NAME
16 --------------------------------------------------------------------------------
17 TAB1
18 TAB2
当对从表执行delete操作的时候会给主表和从表加上lmode=3的锁,这时在Session 48中对表tab1中更改记录:
1 SQL> update tab1 set name='33' where id=1;
2
3 1 row updated.
4
5 SQL> select * from tab1;
6
7 ID NAME
8 ---------- ----------
9 1 33
10
11 SQL> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM') order by 1,2;
12
13 SID TY ID1 ID2 LMODE REQUEST BLOCK
14 ---------- -- ---------- ---------- ---------- ---------- ----------
15 1 TM 73549 0 3 0 0
16 1 TM 73547 0 3 0 0
17 1 TX 131085 737 6 0 0
18 48 TM 73547 0 3 0 0
19 48 TX 524313 972 6 0 0
在主表中并没有被阻塞。
3.给出一个导致死锁的SQL实例。
该实验中将使用到表txt。
首先查看txt的内容,再在一个会话中插入一条记录:
Session 1:
1 SQL> select * from txt;
2
3 no rows selected
4
5 SQL> insert into txt values (2,'cc');
6
7 1 row created.
在另一个会话中插入另一个记录:
Session 48:
1 SQL> insert into txt values (3,'gg');
2
3 1 row created.
此时在Session 1中插入与Session 48一样的记录:
在Session 62中插入与Session最初的记录:
此时两个Session都被阻塞了,而且是session 48先阻塞了Session 1,Session 1再阻塞了Session 48,这就产生了死锁。这时Oracle会自动解决死锁的问题,把先前锁住的会话强制结束,并报出ORA 60错误。
1 SQL> insert into txt values (3,'gg');
2 insert into txt values (3,'gg')
3 *
4 ERROR at line 1:
5 ORA-00060: deadlock detected while waiting for resource
Oracle Lock(Enqueues)的更多相关文章
- [Oracle] Lock&Latch梳理
Oracle lock&latch 1. 概述 4种锁机制 lock latch pin mutex 保证资源在并发访问和修改时不被破坏 锁类型 行为 持有时间 级别 保护类型 lock 队列 ...
- Oracle Lock 概述
按锁的机制分类 排他锁( X ):如果事务T对对象A加上排他锁,则只允许T对A对象读取和修改,其他事务不能对A增加任何锁,直到T释放加载A上的排他锁 共享锁( S ):如果事务T对表A加上共享锁,则事 ...
- [整理]Oracle LOCK 机制
数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性.锁机制用于管理对 ...
- ORACLE基础之oracle锁(oracle lock mode)详解
ORACLE里锁有以下几种模式: 0:none 1:null 空 2:Row-S 行共享(RS):共享表锁,sub share 3:Row-X 行独占(RX):用于行的修改,sub exclusiv ...
- oracle lock
数据库锁介绍: https://www.cnblogs.com/springsnow/p/9990295.html#_label2_0 总结1:查询oracle锁定的表: 1.锁相关表 SELECT ...
- Oracle 动态视图1 V$LOCK
v$lock显示数据库当前持有锁情况 Column Datatype Description SID NUMBER 会话ID TYPE VARCHAR2(2) 表示锁的类型.值包括TM,TX,等 ID ...
- 一篇分析诊断被"hang"住数据库的资料(Oracle Performance Diagnostic Guide——Hang/Locking)
该资料已上传至本人QQ群空间,如需该资料,可到本人QQ群空间查找.下面贴表文本: Oracle Performance Diagnostic GuideHang/LockingVersion 3.1. ...
- DB2和Oracle区别
转 http://blog.chinaunix.net/uid-7374279-id-2057574.html 写在前面:今天客户来访(日本人),问我DB2和Oracle区别.因为不是DBA(勉强的理 ...
- SQL SERVER锁(LOCK)知识及锁应用
提示:这里所摘抄的关于锁的知识有的是不同sql server版本的,对应于特定版本时会有问题. 一 关于锁的基础知识 (一). 为什么要引入锁 当多个用户同时对数据库的并发操作时会带来以下数据不一致的 ...
随机推荐
- install ros-indigo-tf
sudo apt-get install ros-indigo-tf
- Observer(观察者)
意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新. 适用性: 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面.将这二者封装在独立 ...
- 使用git bush 生成github SSH公钥
1 如果没有安装ssh,那么使用下面的指令 sudo apt-get install ssh 2 检查SSH公钥 cd ~/.ssh 看看存不存在.ssh,如果存在的话,掠过下一步:不存在的请看下一步 ...
- linux下给cpu加压
计算pi: time (echo "scale=500;4*a(1)"|bc -l -q) #!/bin/bashfor i in `seq 1 1000`do (time ...
- III USP Freshmen ContestH. MaratonIME gets candies
这题挺有意思的,刚开始不会这交互题,模仿着做了一题就会了,蛮简单 的 这题我用2分,结果wa了,想了一下发现,1到1e9二分50次完全不够用啊,那就转换一下思维,先求出在10^n~10^(n+1)的n ...
- torchnet package (2)
torchnet package (2) torchnet torch7 Dataset Iterators 尽管是用for loop语句很容易处理Dataset,但有时希望以on-the-fly m ...
- POJ-3744-概率dp+矩阵幂(分段)
Scout YYF I Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10214 Accepted: 2980 Desc ...
- hdu 3697 10 福州 现场 H - Selecting courses 贪心 难度:0
Description A new Semester is coming and students are troubling for selecting courses. Students ...
- 网路防火墙iptables
linux操作系统自身可以充当交换机,还可以当路由器,也就是说linux多网卡之间拥有互相转发数据包的能力,这种能力的实现主要依靠的是防火墙的功能进行数据包的转发和入站. 路由选择点,就是在一个点分辨 ...
- oracle创建触发器
create or replace trigger 触发器名字 触发时间 触发事件 after(before) insert or update or delete on 表名 for each r ...