简单演示 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 锁是表级共享锁,表通常看作一个段,当某个表有几个段时,每个段都会分别加上锁。

原文地址:https://www.cnblogs.com/liuning8023/p/2971946.html