达梦 8 实现数据库并发控制 —— 锁

本文主要描述了在数据库并发控制下怎么保护数据的一致性和正确性,引入了锁机制。通过锁模式、锁粒度两个方面来介绍锁。

1 并发控制场景描述

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

2 锁模式

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

排他锁、意向共享锁和意向排他锁。

2.1 共享锁

共享锁(Share Lock,简称 S 锁)用于读操作防止其他事务修改正在访问的对象

这种封锁模式允许多个事务同时并发读取相同的资源,但是不允许任何事务修改这个资源。

2.2 排他锁

排他锁(Exclusive Lock,简称 X 锁)用于写操作,以独占的方式访问对象,不允许任

何其他事务访问被封锁对象;防止多个事务同时修改相同的数据,避免引发数据错误;防止

访问一个正在被修改的对象,避免引发数据不一致。一般在修改对象定义时使用。

2.3 意向锁

意向锁(Intent Lock)用于读取或修改被访问对象数据时使用,多个事务可以同时对

相同对象上意向锁,DM 支持两种意向锁:

1) 意向共享锁(Intent Share Lock,简称 IS 锁):一般在只读访问对象时使用;

2) 意向排他锁(Intent Exclusive Lock,简称 IX 锁):一般在修改对象数据时使用。

四种锁模式的相容矩阵如下表所示,其中“Y”表示相容;“N”表示不相容。如表中第二行

第二列为“Y”,表示如果某个事务已经加了 IS 锁时,其他事务还可以继续添加 IS 锁,第二行

第五列为“N”,表示如果某个事务已经加了 IS 锁时,其他事务不能添加 X 锁。

3 锁粒度

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

3.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 中不再有行锁

的概念。

3.2 对象锁

对象锁是 DM 新引入的一种锁,通过统一的对象 ID 进行封锁,将对数据字典的封锁和表锁合并为对象锁,以达到减少封锁冲突、提升系统并发性能的目的。我们先看一下通常数据字典锁和表锁各自应承担的功能:

1) 数据字典锁:用来保护数据字典对象的并发访问,解决 DDL 并发和 DDL/DML 并发

问题,防止多个事务同时修改同一个对象的字典定义,确保对同一个对象的 DDL

操作是串行执行的。并防止一个事务在修改字典定义的同时,另外一个事务修改对

应表的数据。

2) 表锁:表锁用来保护表数据的完整性,防止多个事务同时采用批量方式插入、更新一张表,防止向正在使用 FAST LOADER 工具装载数据的表中插入数据等,保证这些优化后数据操作的正确性。此外,表锁还有一个作用,避免对存在未提交修改的表执行 ALTER TABLE、TRUNCATE TABLE 操作。

4 显式锁定表

用户可以根据自己的需要显式的对表对象进行封锁。显式锁定表的语法如下:

LOCK TABLE <table_name> IN <lock_mode> MODE [NOWAIT];

lock_mode 是锁定的模式,可以选择的模式有 INTENT SHARE(意向共享)、INTENT

EXCLUSIVE(意向排他)、SHARE(共享)和 EXCLUSIVE(排他)。

5 模拟锁等待

会话1:手动为t1 表(id=1060 通过查询sysobjects数据字典获取)加X锁,lock table t1 X锁

lock table t1 in exclusive mode;

会话2:做同样的操作

lock table t1 in exclusive mode;------等待

会话3:做同样的操作

Drop table t1;------等待

查看锁的状态:

select * from v$lock where table_id=1060;

查看会话和事务的信息:

select * from v$trx;

select * from v$sessions;

select * from v$trxwait;

关闭21492对应的会话:

call sp_close_session(139769443065480);

再次查看锁的状态:

select * from v$lock where table_id=1060;

select * from v$trxwait;

select * from v$trx;

以上为锁阻塞,出现这种情况一般是应用的BUG,需要调整应用的逻辑结构,尽量形成短事务,快速提交。

具体详情请参考 管理事务 | 达梦技术文档

至此结束!

  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值