设为首页 收藏本站
查看: 967|回复: 6

[经验分享] Oracle LOCK内部机制及最佳实践系列

[复制链接]

尚未签到

发表于 2012-12-12 17:47:14 | 显示全部楼层 |阅读模式


引言:Oracle 锁在我一开始接触的时候会有一种高深莫测的感觉,就像是遥远的外星人看不见摸不着但是能感觉到,我在实际的工作中就遇到过ORA-00054: resource busy acquire with nowait specified错误不能插入表,当时知道是被锁定了,根据V$LOCK也定位出[url=]阻塞[/url]的会话了,但不知道如何长久的解决它,究其原因就是不清楚内部机制与释放原理,下面根据例子来揭开锁的面纱,走进Oracle锁的世界。

分别模拟insert,update和delete造成阻塞的示例,并对v$lock中的相应的信息进行说明,给出[url=]SQL[/url]演示。

LEO1@LEO1> create user leo2 identified by leo2 default tablespace leo1;       新创建一个LEO2用户
User created.
LEO1@LEO1> grant connect,resource to leo2;                                             授予基本权限
Grant succeeded.
LEO1@LEO1> select owner,table_name,tablespace_name from dba_tables where wner='LEO1';
OWNER                          TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
LEO1                               LEO_WAGE                       LEO1

LEO1@LEO1> create [url=]table[/url] t1 (id int primary key);     创建t1表,设置id列为主键
Table created.
LEO1@LEO1> insert into t1 values(1);                  
1 row created.
LEO1@LEO1> select * from t1;
        ID
----------
         1
LEO2@LEO1> insert into leo1.t1 values(1);             当没有提交,在插入同样的values时就发生了对会话的阻塞,hang在这里不能前进
LEO1@LEO1> commit;                                          必须提交后,阻塞才终止,也就是说commit可以释放阻塞
Commit complete.
LEO2@LEO1> insert into leo1.t1 values(1);             因为已经有了1值,故违反了主键约束
insert into leo1.t1 values(1)
*
ERROR at line 1:
ORA-00001: unique constraint (LEO1.SYS_C0010817) violated

update 锁阻塞

LEO1@LEO1> select * from t1;
        ID
----------
         1
         2
       100
LEO1@LEO1> update t1 set id=200 where id=100;       更新一行没有提交,没有提交的事物对别人是不可见的,但在物理块上真真切切的修改了,他人只能访问undo回滚段中镜像
1 row updated.
LEO2@LEO1> update leo1.t1 set id=300 where id=100;   我们在会话leo2上也更新同一个表里的同一行,此时hang住了不动了,因为2个会话在争用同一条记录的修改权
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where [url=]type[/url] in ('TM','TX') order by 1,2;        一般影响业务性能的就 TM and TX 锁
       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       138 TM      73449          0          3          0          0
       138 TX     196615      912          6          0          1
       156 TM      73449          0          3          0          0
       156 TX     196615      912          0          6          0

SID:会话id号
TYPE:锁的类型
ID1:会话操作对象的id号
ID2:ID1+ID2 定位回滚段上的一个地址(即修改之前数据镜像地址),由于138和156会话是一样的说明指向的是同一个地址,换句话说操作的是同一行数据
LMODE:锁模式,不同的数字代表不同的锁模式  例如  0 现在没有申请到锁   3  共享锁模式(段级共享锁)   6  排他锁模式   锁的级别越高限制越多
REQUEST:目前会话没有锁,正在申请的锁模式  例如  0 没有正在申请的锁,说明已经有锁了   6  现在正在申请6号锁,目前因为没有才申请
BLOCK:当前正在阻塞几个会话  例如  1  当前正在阻塞一个会话  2  当前正在阻塞两个会话
锁的实质:是维护一个事务完整性的,锁的信息是数据块的一个属性,是物理的,并不是逻辑上属于某个表或者某几行的。

LEO1@LEO1> select distinct sid from v$mystat;        这个会话当前id是138,我们怎么区分呢?=> LEO1用户=138     LEO2用户=156
       SID
----------
       138
LEO1@LEO1> select object_name from dba_objects where object_id=73449;                     138会话操作的对象是T1表
OBJECT_NAME
--------------------------------------------------------------------------------
T1
说明:138会话在T表上加了TM和TX锁,TM锁模式为3(共享锁) TX锁模式6(排他锁),目前TX锁正在阻塞一个会话(就是156会话)。
156 会话就是当前被阻塞的会话,156会话操作对象也是T1表(ID1都一样的),TM锁模式也为3(共享锁就是有几个会话就可以创建几个共享锁,同时存在),TX现在还没有申请到锁,正在申请6号锁,而这个6号锁就是138会话所持有的(因为2个会话操作的是同一行数据)
LEO1@LEO1> select sid,event from v$session_wait where sid in (138,156);         从会话等待视图上可以看出,有哪些会话由于什么原因导致等待事件不能前进
       SID EVENT
---------- ----------------------------------------------------------------
       138 SQL*Net message to client
       156 enq: TX - row [url=]lock[/url] contention
156会话由于TX锁争用原因导致hang住不能前进,enq=enqueues队列锁(通常和业务有关,为了保护业务的锁)
小结:现在我们应该很晴朗的看出138会话阻塞156会话,以及阻塞的原因和会话数和锁类型

insert 锁阻塞

LEO1@LEO1> select * from leo1.t1;
        ID
----------
         1
         2
       200
LEO1@LEO1> insert into leo1.t1 values(3);       插入一行但没有提交,这是一个未决状态,还不清楚是否真正插入
1 row created.
LEO2@LEO1> insert into leo1.t1 values(3);       我们在会话leo2上也插入同样的数据,此时hang住了不动了,这里实际上是插入了2条独立的记录,不能认为是同一条记录,只是值一样
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       138 TM      73449          0          3          0          0
       138 TX      65555        681          6          0          1        138正在阻塞另一个会话
       156 TM      73449          0          3          0          0
       156 TX     458766       669          6          0          0        这也显示了在插入第二条记录时没有被阻塞
       156 TX      65555        681          0          4          0        而在插入的修改值相同后被阻塞了,锁的级别是4
insert 时v$lock视图里面多了一个TX锁(就是最后一行),首先说明一下insert和update delete 操作的不同,后两者都是对同一条记录的修改权争用产生阻塞(这里不涉及修改值的问题),而insert操作实际上插入了2条不同的记录,由于这2条不同的记录的修改值一样违反了主键约束从而产生阻塞,实际是对修改值的相同产生了阻塞。锁的级别为4,这种锁比update的锁级别要低,锁的级别越低限制越少。

delete 锁阻塞

LEO1@LEO1> select * from leo1.t1;                  t1表中有5条记录,我们计划删除的是最后1条
        ID
----------
         1
         2
         4
         5
       200
LEO1@LEO1> delete from leo1.t1 where id=200;       138会话正在删除id=200的记录,但是没有提交,此时就是加上一个TM TX锁
1 row deleted.
LEO2@LEO1> delete from leo1.t1 where id=200;       这时158会话也做同样的动作,就被hang住了不能动了,下面我们来看看锁定情况
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       138 TM      73449          0          3          0          0
       138 TX     524316      935          6          0          1               138会话持有一个6级排他锁,正在阻塞一个会话
       156 TM      73449          0          3          0          0
       156 TX     524316      935          0          6          0               156会话被阻塞住了没有获得锁,正在申请一个6级锁
LEO1@LEO1> select object_name from dba_objects where object_id=73449;              现在可知锁定的就是t1表
OBJECT_NAME
--------------------------------------------------------------------------------
T1
LEO1@LEO1> select sid,event from v$session_wait where sid in (138,156);            从会话等待视图上也可以看出138阻塞了156会话
       SID EVENT
---------- ----------------------------------------------------------------
       138 SQL*Net message from client
       156 enq: TX - row lock contention
156会话由于TX锁争用原因导致hang住不能前进,enq=enqueues队列锁
小结:我们在了解锁的同时,也要在业务设计的流程上尽量去避免它们的发生,比如说2个人的工作没有协调好,在同一时间去做了同一件事,这就有可能产生锁。

select...for update 锁阻塞                                     这是一种对结果集修改的保护机制

场景:一次性修改多条记录的时候会用到这个命令,起到锁定结果集的效果,这也是结果集修改引起的阻塞
LEO1@LEO1> select * from leo1.t1;      
        ID
----------
         1
         2
         3
       200
LEO1@LEO1> select * from leo1.t1 where id<=3 for update;        如果我们想对查询出的结果集进行独占,并且此时不允许其他会话进行修改,可以这么来写
        ID
----------
         1
         2
         3
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73449          0          3          0          0
       138 TX             589839      915          6          0          0           这3行记录都已经被TX锁锁定了,在没有提交之前别人不能修改
LEO2@LEO1> update leo1.t1 set id=4 where id=1;
LEO2@LEO1> update leo1.t1 set id=4 where id=2;
LEO2@LEO1> update leo1.t1 set id=4 where id=3;                   我们在会话leo2上测试更新结果集中的每条记录,都会hang住了不能前进,说明这
个结果集已经整体被锁定
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       138 TM      73449          0          3          0          0
       138 TX     589839      915          6          0          1      138正在阻塞另一个会话
       156 TM      73449          0          3          0          0
       156 TX     589839      915          0          6          0

LEO1=138会话   LEO2=156会话,我们可以看出138会话阻塞156会话,156会话TX在请求一个6号排他锁,因为2个会话都在修改同一个结果集。这种方法可以一次性锁定n行记录。
重点:一个表上只能有一个6号锁


模拟RI锁定导致[url=]阻塞[/url]的场景,并分析v$lock相应的锁定信息,给出[url=]SQL[/url]演示。

LEO1@LEO1> create [url=]table[/url] a (id int primary key);                     a是主表,定义了id字段为主键
Table created.
LEO1@LEO1> create table b (id references a(id));                    b是从表,id字段是引用主表的id字段
Table created.
LEO1@LEO1> insert into a values(1);                                      往主表a中插入一条数据但没有提交,事务没有结束会产生锁定
1 row created.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where [url=]type[/url] in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73465          0          3          0          0     insert由于有从属关系因此会在2个表上都加3号共享锁
       138 TM              73467          0          3          0          0     
       138 TX             196640      940          6          0          0
LEO1@LEO1> select object_name from dba_objects where object_id in (73465,73467);  ID1就是138会话操作的对象id,我们会在主表和从表上都加上表级锁
OBJECT_NAME
--------------------------------------------------------------------------------
A           73465
B           73467
LEO1@LEO1> commit;                                                   提交之后释放锁
Commit complete.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;    锁会随着事务的结束而释放
no rows selected
LEO1@LEO1> select * from a;                                        a表中有一条记录
        ID
----------
         1
LEO1@LEO1> select * from b;
no rows selected
LEO1@LEO1> update a set id=100 where id=1;                           主表a上更新了一条记录
1 row updated.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73465          0          3          0          0          update现在只对主表有锁定,从表没有锁定
       138 TX             196634      941          6          0          0
LEO1@LEO1> commit;                                                   提交之后释放锁
Commit complete.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;      现在没有锁了
no rows selected
LEO1@LEO1> select * from a;          主表里的值已经更新了
        ID
----------
       100
LEO1@LEO1> delete from a;            
1 row deleted.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73465          0          3          0          0         delete也是只对主表有锁定,从表没有锁定
       138 TX             655375      705          6          0          0
LEO1@LEO1> commit;                                                               提交释放锁
Commit complete.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
no rows selected

LEO1@LEO1> insert into b values(2);                                   
insert into b values(2)
*
ERROR at line 1:
ORA-02291: integrity constraint (LEO1.SYS_C0010831) violated - parent key not found   直接给从表插入记录,如果主表没有的话,会报错违反引用完整性约束,没有主表依据

LEO1@LEO1> insert into a values(2);      我们只能先给主表插入
1 row created.
LEO1@LEO1> insert into b values(2);      再给从表插入才可以,因为从表的数据必须在主表里先存在,才能正常引用
1 row created.
LEO1@LEO1> select * from a;              主表有了
        ID
----------
         2
LEO1@LEO1> select * from b;              从表有了
        ID
----------
         2
LEO1@LEO1> select * from a;              主表有3
        ID
----------
         2
         3
LEO1@LEO1> insert into b values(3);   才能给从表插入
1 row created.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73465          0          3          0          0    从表的insert也会对主从表同时加锁
       138 TM              73467          0          3          0          0
       138 TX             393246      939          6          0          0
LEO1@LEO1> select * from b;
        ID
----------
         2
         3
LEO1@LEO1> commit;                释放锁
Commit complete.
LEO1@LEO1> delete from b;       删除从表
2 rows deleted.

LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73465          0          3          0          0    从表delete也会对主从表同时加锁
       138 TM              73467          0          3          0          0
       138 TX             196620      944          6          0          0

LEO1@LEO1> commit;                                  释放锁
Commit complete.
LEO1@LEO1> select * from a;                      主表有2条记录
        ID
----------
         2
         3
LEO1@LEO1> select * from b;                      从表没有记录
no rows selected

LEO1@LEO1> insert into a values(4);            向主表插入1条记录,因为没有提交所以是未决状态
1 row created.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73465          0          3          0          0      此时对主从表都加了锁定
       138 TM              73467          0          3          0          0
       138 TX             589834      937          6          0          0
LEO2@LEO1> insert into leo1.b values(4);          此时向从表也插入1条记录,由于从表的数据必须引用自主表,而主表数据现在是一种未决状态,所以hang住不能前进
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73465          0          3          0          0
       138 TM              73467          0          3          0          0
       138 TX             589834      937          6          0          1      138会话阻塞156会话,这个6代表已经插入成功,但修改值还是未决状态
       156 TM              73467          0          3          0          0
       156 TM              73465          0          3          0          0
       156 TX             393221      942          6          0          0      这个6代表也已经插入成功,但修改值还是未决状态
       156 TX             589834      937          0          4          0      主从表插入后产生了2个TX锁,这说明这是2条不同的记录,2个独立的记录,不是争用同一条记录

小结:之所以还有一个TX锁正在申请4号锁,是因为2条记录的修改值都是未决状态违反了引用完整性约束从而产生阻塞。导致156会话hang住不能前进。


自己构想一个使用手工锁定解决一种业务需求的场景,并给出[url=]SQL[/url]演示。

场景:手工锁定一个表,例如 我们在做一个秘密交易的时候,谈好的价格就不能变了,必须一手交钱一手交货完成交易,为了保证价格安全,我们先把价格表锁定,这期间不允许篡改,保证完成交易
LEO1@LEO1> [url=]lock[/url] [url=]table[/url] t1 in share mode;                                    手工锁定一个表,设置锁的级别为4
Table(s) Locked.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where [url=]type[/url] in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73449          0          4          0          0             已经在T1表上加上了4号锁,除了当前会话外[url=]阻塞[/url]其他会话进行修改
LEO2@LEO1> insert into leo1.t1 values(5);                                   我们在会话leo2上插入一条记录,此时hang住了不动了
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73449          0          4          0          1     
       156 TM              73449          0          0          3          0
这就是由于我们加了4号锁除了当前会话外阻塞156会话进行修改,156会话默认可以获得一个3号锁,由于3号和4号互斥不能共存,所以没有获得锁,正在等待申请3号锁
LEO1@LEO1> commit;                                                                   锁跟着事务的结束而释放,commit   rollback都行
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;     此时没有锁信息了
no rows selected


深入分析mode 2-6 的TM锁相互间的互斥关系

[url=]Oracle[/url] TM锁的类型
锁模式

锁描述

含义

锁定表的SQL

0

None



1

Null

空,本模式是oracle预留模式


2

Row Share(RS)
又叫(SS

行级共享锁,是限制最少的TM锁,可以提供最高程度的并发性。其他会话可以对锁定的表进行任何类型的DML操作,还可以与其他会话锁并存

[url=]Lock[/url] table t in row share mode;

3

Row Exclusive Table Lock(RX)
又叫(SX)

行级排他锁,通常已经有事务在修改行或者select…for update修改结果集。允许其他事务对锁定的表进行select  insert  update  deletelock table同时锁定一张表

Lock table t in row 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;

Oracle锁模式互斥关系图
锁模式

锁名称

允许级别

互斥级别

2

行级共享锁

2 3 4 5

6

3

行级排他锁

2 3

4 5 6

4

共享锁

2 4

3 5 6

5

共享行级排他锁

2

3 4 5 6

6

排他锁


2 3 4 5 6

实验锁互斥
准备工作
LEO1@LEO1> select distinct sid from v$mystat;           LEO1用户的会话id=138
       SID
----------------------------
       138
LEO2@LEO1> select distinct sid from v$mystat;           LEO2用户的会话id=156
       SID
----------------------------
       156
LEO1@LEO1> create table lock1 (x int primary key);   创建lock1表,设置x列为主键
Table created.
LEO1@LEO1> insert into lock1 values(1);                     我们插入1
1 row created.
LEO1@LEO1> commit;                        提交
Commit complete.
LEO1@LEO1> select * from lock1;      现在只有一条记录,并且没有锁
         X
----------------------------
         1
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
no rows selected

行级共享锁Row Share(RS)  2


LEO1@LEO1>lock table lock1 in row share mode;        lock1表设置为行级共享锁模式
Table(s) Locked.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- -------------------- ---------- ---------- ---------- ---------- ---------- --
      138TM              73472          0         2          0          0
模式标识:2
LEO1@LEO1> select object_name from dba_objects where object_id=73472;      lock1表对象id73472
OBJECT_NAME
----------------------------------------------------------------------------------------------------
LOCK1

LEO2@LEO1>insert into leo1.lock1 values(2);
1 row created.
LEO2@LEO1> select * from leo1.lock1;
         X
----------
         1
         2
LEO2@LEO1>delete from leo1.lock1 where x=1;
1 row deleted.
LEO2@LEO1> select * from leo1.lock1;
         X
----------
         2
LEO2@LEO1>update leo1.lock1 set x=10 where x=2;
1 row updated.
LEO2@LEO1> select * from leo1.lock1;
         X
----------
        10
LEO2@LEO1>select * from leo1.lock1 for update;
         X
----------
        10
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- -------------- ---------- ---------- ---------- -----------------
      138TM              73472          0         2          0          0
      156TM              73472          0          3          0          0
       156 TX              524321     936          6          0          0
小结:行级共享锁,是限制最少的TM锁,可以提供最高程度的并发性。其他会话可以对锁定的表进行任何类型的DML操作,还可以与其他会话锁并存。

行级排他锁  Row Exclusive Table Lock(RX)  3


LEO1@LEO1>lock table leo1.lock1 in row exclusive mode;              lock1表设置为行级排他锁
Table(s) Locked.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- -------------------- ---------- ---------- --------------------
      138TM              73472          0         3          0          0
模式标识:3
3级锁是一个灵活性比较大的锁,insert delete update都可以产生一个3级锁,也允许其他事务来修改锁定的表
LEO1@LEO1>select * from leo1.lock1;
         X
-----------------
        10
        20
        30
        40
        50
会话27
LEO1@LEO1>update leo1.lock1 set x=100 where x=10;
1 row updated.
LEO1@LEO1> select * from leo1.lock1;              已经被修改了
         X
------------------
        20
        30
        40
        50
      100
会话156
LEO2@LEO1>insert into leo1.lock1 values(60);  也已经插入了,注意没有提交的事务对别人是不可见的
1 row created.
LEO2@LEO1> select * from leo1.lock1;
         X
-----------------
        10
        20
        30
        40
        50
        60
会话146
LEO2@LEO1>delete from leo1.lock1 where x=20;   已经删除
1 row deleted.
LEO2@LEO1> select * from leo1.lock1;
         X
--------------------
        10
        30
        40
        50
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ---------------- ----------
        27TM              73472          0          3          0          0
        27TX              327698    1144          6          0          0
       138 TM              73472          0          3          0          0
      146TM              73472          0          3          0          0
      146TX              196626      975          6          0          0
      156TM              73472          0          3          0          0
      156TX              262163      782          6          0          0
大家都是共存的,谁也没有[url=]阻塞[/url]谁,block列全部是0
小结:行级排他锁,通常已经有事务在修改行或者select…for update修改结果集。允许其他事务对锁定的表进行select  insert  update  deletelock table同时锁定一张表。

共享锁  Share Table Lock(S)  4

LEO1@LEO1> select * from leo1.lock1;                              还是有5条记录
         X
-----------------
        10
        20
        30
        40
        50
LEO1@LEO1>lock table leo1.lock1 in share mode;           lock1表设置为共享锁
Table(s) Locked.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- -------------- ---------- ---------- ---------- ---------- -----
      138TM              73472          0         4          0          0
模式标识:4
4级锁禁止其他会话对锁定的表进行DML操作但可以select查询,还允许多个事物一起持有
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ------------------ ---------- ---------- ------------------ ----
        13 TM             73472          0          0          4          0
      27TM              73472          0          0         3          0
       138 TM            73472          0          4          0          1
      146TM            73472          0          0         3         0
      156TM            73472          0          0         3         0
27 146 156会话都已经被阻塞了,有的朋友会问4级锁可以和4级锁共存这里为什么不行呢。呵呵因为有3级锁在捣乱,4级和3级是不能共存的,所以我们把所有的3级锁都释放就可以了,我们来看一下
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- -------------------- ---------- ---------- ---------- ----------
        13TM              73472          0         4          0          0
        27TM              73472          0         2          0          0
      138TM             73472          0         4         0          0
现在4级锁2级锁都可以同时存在了
小结:共享锁,其他事务可以查询锁定的表但不能修改,只允许当前事务修改,但可以多个事务持有它。

共享行级排他锁  Share Row Exclusive Table Lock(SRX)  5

LEO1@LEO1>lock table leo1.lock1 in share row exclusive mode;   lock1表设置为共享行级排他锁
Table(s) Locked.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ------------ -----
      138TM              73472          0         5          0          0
模式标识:5
LEO1@LEO1> select object_name from dba_objects where object_id=73472;  现在锁定的表就是lock1
OBJECT_NAME
--------------------------------------------------------------------------------
LOCK1
会话138
LEO1@LEO1> select * from leo1.lock1;   现在表里有5条记录,我们看看其他会话能不能修改表
         X
--------------------
        10
        20
        30
        40
        50
会话156
LEO2@LEO1>insert into leo1.lock1 values(60);                  hang住了不能够前进说明被阻塞
会话27
LEO1@LEO1>update leo1.lock1 set x=100 where x=10;     hang住了不能够前进说明被阻塞
会话146
LEO2@LEO1>delete from leo1.lock1 where x=20;              hang住了不能够前进说明被阻塞
那么select… for update当然也会被阻塞的,我们来看看其他事务能不能查询呢!
会话23
LEO2@LEO1> select * from leo1.lock1;
         X
-------------------
        10
        20
        30
        40
        50
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ------------------- ---------- ------------------- ---------- -
        27TM               73472          0          0          3          0
       138 TM              73472          0         5          0          1
      146TM              73472          0          0         3          0
      156TM              73472          0          0         3          0
会话23没有被阻塞可以正常查询耶,这也验证了我们的观点,读操作不会被任何事务阻塞,也不会加锁,27  146  156会话3个行级排他锁都在等待着138会话释放锁
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
        13TM              73472          0         2          0          0
     138TM              73472          0         5          0          0
会话132级锁和会话1385级锁可以共存符合我们的锁互斥关系
小结:共享行级排他锁,同一时间只允许一个事务持有和修改锁定的表,其他事务可以查询但不能修改。

排他锁  Exclusive Table Lock (X)  6

LEO1@LEO1>lock table leo1.lock1 in exclusive mode;      lock1表设置为排他锁,等级最高的锁
Table(s) Locked.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- -------------- ---------- ---------- -------------- ----------
      138TM              73472          0         6          0          0
模式标识:6
会话156
LEO2@LEO1>insert into leo1.lock1 values(60);            
会话27
LEO1@LEO1>update leo1.lock1 set x=100 where x=10;     
会话146
LEO2@LEO1>delete from leo1.lock1 where x=20;         
会话13
LEO2@LEO1>lock table leo1.lock1 in row share mode;      测试锁互斥
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ---------- ---------- -------
        13TM              73472          0          0         2          0        
        27TM              73472          0          0         3          0
      138 TM              73472          0          6          0          1
      146TM              73472          0          0         3          0
      156TM              73472          0          0         3         0
6级锁会阻塞除了自己外的所有会话的事务并且排斥其他的所有锁模式连2级锁都不行,是最高限制的TM锁,当然select还是没有问题的。
小结:排他锁,是限制最高的TM锁,禁止其他事务执行任何类型的DML语句或者锁表。一个表一般只能有一个6号锁。




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-2814-1-1.html 上篇帖子: oracle比较有用的sql语句 下篇帖子: Rhel5 32bit oracle database的安装

尚未签到

发表于 2013-3-14 08:31:22 | 显示全部楼层
写的真的很不错

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-5-16 15:19:59 | 显示全部楼层
沙发!沙发!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-5-20 16:21:05 | 显示全部楼层
我真想亲口管你爷爷叫声:爹!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-5-26 05:21:08 | 显示全部楼层
走过了年少,脚起了水泡

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-6-3 08:29:02 | 显示全部楼层
谢谢楼主,共同发展

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-6-8 00:44:47 | 显示全部楼层
路过,学习下

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表