简单演示 Oracle 数据库并发导致段级锁(表级锁)
本文内容
- 软件环境
- 简单演示 Oracle 数据库并发导致段级锁(表级锁)
本文简单演示并发导致的行级锁。并发是两个以上的用户对同样的数据进行修改(包括插入、删除和修改)。锁的产生是因为并发。没有并发,就没有锁。并发的产生是因为系统需要,系统需要是因为用户需要。
软件环境
- Windows 2003 Server
- Oracle 11g Release 1 (11.1)
简单演示 Oracle 数据库并发导致段级锁(表级锁)
首先,打开一个回话 session 1:
SQL> select distinct sid from v$mystat;
SID
----------
124
SQL> create table t(x int) partition by range(x)(partition p1 values less than(10),partition p2 values less than(maxvalue));
表已创建。
SQL> insert into t values(1);
已创建 1 行。
SQL> select * from t partition(p1);
X
----------
1
SQL> select sid,type,id1,id2,lmode,request,block
2 from v$lock where sid=124;
SID TYPE ID1 ID2 LMODE REQUEST BLOCK
---------- ----- ---------- ---------- ---------- ---------- ----------
124 AE 99 0 4 0 0
124 TM 128807 0 3 0 0
124 TM 128808 0 3 0 0
124 TX 589847 46045 6 0 0
SQL> select object_name, subobject_name
2 from dba_objects
3 where object_id in (128807, 128808);
OBJECT_NAME SUBOBJECT_NAME
--------------- ---------------
T
T P1
SQL>
- 创建分区表 t,包含两个分区,p1和p2。
- 向表插入一条记录,该记录落在分区 p1,p2 分区没有。
- 通过查看 V$LOCK 视图发现,数据库只在表 t 和 p1 分区上设置了 TM 共享锁,但是 p2 上没有。
- 当锁的类型为 TM 时,字段 ID1 表示加锁的对象 ID。通过查看 DBA_OBJECTS 视图可以获得对象名称,128807 和 128808 分别对应 t 表和 t 表的 p1 分区。
再打开一个回话 session 2:
此时,如果我们对 t 表、t 表的 p1 分区和 t 表的 p2 分区做 DDL 操作,会发生什么:
SQL> select distinct sid from v$mystat;
SID
----------
140
SQL> truncate table t;
truncate table t
*
第 1 行出现错误:
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效
SQL> alter table t truncate partition p1;
alter table t truncate partition p1
*
第 1 行出现错误:
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效
SQL> alter table t truncate partition p2;
表被截断。
SQL>
- 只有 p2 分区没加段级锁,所以 p2 上可以进行 DDL 操作。
- TM 锁是一个段级锁,它允许同级别或更低级别的锁,但是拒绝高级别的锁,DDL 操作显然高。Oracle 尽可能地减少锁的影响范围。
SQL> insert into t values(11);
已创建 1 行。
SQL> select * from t partition(p2);
X
----------
11
SQL> select sid,type,id1,id2,lmode,request,block
2 from v$lock where sid in (124,140)
3 order by sid,type;
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
124 AE 99 0 4 0 0
124 TM 128808 0 3 0 0
124 TM 128807 0 3 0 0
124 TX 327711 45817 6 0 0
140 AE 99 0 4 0 0
140 TM 128807 0 3 0 0
140 TM 128809 0 3 0 0
140 TX 196611 45960 6 0 0
已选择8行。
SQL> select object_name, subobject_name
2 from dba_objects
3 where object_id in (128807, 128808, 128809);
OBJECT_NAME SUBOBJECT_NAME
--------------- ---------------
T
T P1
T P2
SQL>
- 当向 p2 分区插入一条数据时,p2 分区也加上了一个共享锁,即ID1=128809。
- TM 锁是表级共享锁,表通常看作一个段,当某个表有几个段时,每个段都会分别加上锁。