达梦数据库锁管理

DM 数据库支持多用户并发访问、修改数据,有可能出现多个事务同时访问、修改相同 数据的情况。若对并发操作不加控制,就可能会访问到不正确的数据,破坏数据的一致性和 正确性。
封锁机制是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据库对象进行操作前,需要先对其封锁。封锁后事务就对该数据库对象有了一定的控制,在该事务释放 锁之前,其他的事务不能对此数据库对象进行相应操作。

一、 锁模式

锁模式指定并发用户如何访问锁定资源。DM 数据库使用四种不同的锁模式:共享锁、
排他锁、意向共享锁和意向排他锁。

  1. 共享锁
    共享锁(Share Lock,简称 S 锁)用于读操作,防止其他事务修改正在访问的对象。
    这种封锁模式允许多个事务同时并发读取相同的资源,但是不允许任何事务修改这个资源。
  2. 排他锁
    排他锁(Exclusive Lock,简称 X 锁)用于写操作,以独占的方式访问对象,不允
    许任何其他事务访问被封锁对象;防止多个事务同时修改相同的数据,避免引发数据错误;防止访问一个正在被修改的对象,避免引发数据不一致。一般在修改对象定义时使用。
  3. 意向锁
    意向锁(Intent Lock)用于读取或修改被访问对象数据时使用,多个事务可以同时对相同对象上意向锁,DM 支持两种意向锁:
  1. 意向共享锁(Intent Share Lock,简称 IS 锁):一般在只读访问对象时使用;
  2. 意向排他锁(Intent Exclusive Lock,简称 IX 锁):一般在修改对象数据时使用。

二、锁粒度

按照封锁对象的不同,锁可以分为 TID 锁和对象锁。

  1. TID 锁
    TID 锁以事务号为封锁对象,为每个活动事务生成一把 TID 锁,代替了其他数据库行
    锁的功能,防止多个事务同时修改同一行记录。DM 实现的是行级多版本,每一行记录隐含
    一个 TID 字段,用于事务可见性判断。执行 INSERT、DELETE、UPDATE 操作时,设置事务号到 TID 字段。这相当于隐式地对记录上了一把 TID 锁,INSERT、DELETE、UPDATE 操作不再需要额外的行锁,避免了大量行锁对系统资源的消耗。只有多个事务同时修改同一行记录时,才会产生新的 TID 锁。
    例如,当事务 T1(事务号为 TID1)试图修改某行数据,而该行数据正在被另一个事务 T2
    (事务号为 TID2)修改,此时事务 T1 会生成一个新的 TID 锁,其锁对象为事务号 TID2,而非事务 T2。
    同时多版本写不阻塞读的特性,SELECT 操作已经消除了行锁,因此 DM 中不再有行锁的概念。
  2. 对象锁
    对象锁是 DM 新引入的一种锁,通过统一的对象 ID 进行封锁,将对数据字典的封锁和 表锁合并为对象锁,以达到减少封锁冲突、提升系统并发性能的目的。我们先看一下通常数据字典锁和表锁各自应承担的功能:
  1. 数据字典锁:用来保护数据字典对象的并发访问,解决 DDL 并发和 DDL/DML 并发问题,防止多个事务同时修改同一个对象的字典定义,确保对同一个对象的 DDL操作是串行执行的。并防止一个事务在修改字典定义的同时,另外一个事务修改对应表的数据。
  2. 表锁:表锁用来保护表数据的完整性,防止多个事务同时采用批量方式插入、更新一张表,防止向正在使用 FAST LOADER 工具装载数据的表中插入数据等,保证这些优化后数据操作的正确性。此外,表锁还有一个作用,避免对存在未提交修改的表执行 ALTER TABLE、TRUNCATE TABLE 操作。
    为了实现与数据字典锁和表锁相同的封锁效果,从逻辑上将对象锁的封锁动作分为四类:
    a) 独占访问(EXCLUSIVE ACCESS),不允许其他事务修改对象,不允许其他事务访问对象,使用 X 方式封锁
    b) 独占修改(EXCLUSIVE MODIFY),不允许其他事务修改对象,允许其他事务共享访问对象,使用 S + IX 方式封锁
    c) 共享修改(SHARE MODIFY),允许其他事务共享修改对象,允许其他事务共享访问对象,使用 IX 方式封锁
    d) 共享访问(SHARE ACCESS),允许其他事务共享修改对象,允许其他事务共享访问对象,使用 IS 方式封锁
  1. 显式锁定表
    用户可以根据自己的需要显式的对表对象进行封锁。显式锁定表的语法如下:
    LOCK TABLE <table_name> IN <lock_mode> MODE [NOWAIT];
    lock_mode 是锁定的模式,可以选择的模式有 INTENT SHARE(意向共享)、INTENT EXCLUSIVE(意向排他)、SHARE(共享)和 EXCLUSIVE(排他),其含义分别如下:
  1. 意向共享:不允许其他事务独占修改该表。意向共享锁定后,不同事务可以同时增、删、改、查该表的数据,也支持在该表上创建索引,但不支持修改该表的定义;
  2. 意向排他:不允许其他事务独占访问和独占修改该表。被意向排他后,不同事务可以同时增、删、改、查该表的数据,不支持在该表上创建索引,也不支持修改该表定义;
  3. 共享:只允许其他事务共享访问该表,仅允许其他事务查询表中的数据,但不允许增、删、改该表的数据;
  4. 排他:以独占访问方式锁定整个表,不允许其他事务访问该表,是封锁力度最大的一种封锁方式。
    当使用 NOWAIT 时,若不能立即上锁成功则立刻返回报错信息,不再等待。
    三、 查看锁
    为了方便用户查看当前系统中锁的状态,DM 数据库专门提供了一个 V L O C K 动 态 视 图 。 通 过 该 视 图 , 用 户 可 以 查 看 到 系 统 当 前 所 有 锁 的 详 细 信 息 , 如 锁 的 内 存 地 址 、 所 属 事 务 I D 、 锁 类 型 、 锁 模 式 等 。 用 户 可 以 通 过 执 行 如 下 语 句 查 看 锁 信 息 : S E L E C T ∗ F R O M V LOCK 动态视图。 通过该视图,用户可以查看到系统当前所有锁的详细信息,如锁的内存地址、所属事务 ID、锁类型、锁模式等。用户可以通过执行如下语句查看锁信息: SELECT * FROM V LOCKIDSELECTFROMVLOCK;
    其中 ADDR 列表示锁的内存地址;TRX_ID 列表示锁所属的事务 ID;LTYPE 列表示锁的类型,可能是 OBJECT(对象锁)或者 TID(TID 锁);LMODE 表示锁的模式,可能的取值有 S(共享锁)、X(排他锁)、IS(意向共享锁)、IX(意向排他锁);BLOCKED 列表示锁是否处于上锁等待状态,0 表示已上锁成功,1 表示处于上锁等待状态;TABLE_ID 列对于对象锁,表示表对象或字典对象的 ID,对于 TID 锁,表示封锁记录对应的表 ID;ROW_IDX列为 TID 锁封锁记录的行信息;TID 列为 TID 锁对象事务ID。
    四、锁处理示例
    创建测试表,并插入一条数据:
create table TEST1(ID int,name varchar(30));
insert into TEST1 values(100,'WANG');

在一个会话中进行更新:

update TEST1 set name = 'LI' where id = 100;

在另一个会话中再次对这条数据进行更新:

update TEST1 set name = 'ZHANG' where id = 100;

使用命令查看被锁会话

select a.*,b.NAME,c.SESS_ID from v$lock a left join sysobjects b on b.ID=a.TABLE_ID left join v$sessions c on a.TRX_ID=c.TRX_ID;

LINEID     ADDR                 TRX_ID               LTYPE  LMODE BLOCKED     TABLE_ID    ROW_IDX             
---------- -------------------- -------------------- ------ ----- ----------- ----------- --------------------
           TID                  IGN_FLAG    HLCK_EP     NAME  SESS_ID             
           -------------------- ----------- ----------- ----- --------------------
1          102811088            26242                OBJECT IX    0           1345        -1
           0                    0           255         TEST1 140053649103912

2          102811216            26243                OBJECT IX    0           1345        0
           0                    0           255         TEST1 140053514884728

3          103073232            26242                TID    X     0           -1          -1
           26242                0           255         NULL  140053649103912

查到SESS_ID后使用下面函数KILL掉对应的SESSION;

sp_close_session(26243);
DMSQL executed successfully
used time: 0.297(ms). Execute id is 103.

使用命令查询会话中等待事务

select * from v$trxwait;
no rows
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值