达梦数据库锁理解
1 数据库锁解决了什么问题?
在处理高并发事务时,最常遇到的挑战之一就是如何保证数据的 一致性 和 并发性能 的平衡。
而锁(Lock) 正是解决这一问题的核心机制。
锁的作用:通过控制并发事务对数据的访问顺序,确保数据的一致性。
例如
经典案例:两个售票终端同时处理同一航班座位
时间 终端A 终端B
T1 查询座位5A状态为空 查询座位5A状态为空
T2 准备预订座位5A 准备预订座位5A
T3 提交预订成功 提交预订成功
后果:同一座位被重复售出
解决方案:通过锁机制保证事务之间的隔离性
比如终端A事务开启时,通过加锁,使B阻塞,就不存在重复售出问题
2 达梦锁模式分类
各位锁的演示放在最后一章
达梦的锁分成3种
共享锁、排他锁、意向锁
锁可以分为两大类,悲观锁和乐观锁
乐观锁:属于业务逻辑类的锁,基于版本号和时间戳来判断
悲观锁:本文讲解的所有锁都是悲观锁,数据库自动管理的锁
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 锁;

3 达梦锁粒度
3.1 TID 锁
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 对象锁(表和字典锁)
对象锁可以理解为表和字典锁的合并,为了减少封锁冲突、提升系统并发性能的目的
为了实现与数据字典锁和表锁相同的封锁效果,从逻辑上将对象锁的封锁动作分为四类:
a) 独占访问(EXCLUSIVE ACCESS),不允许其他事务修改对象,不允许其他事务访问对象,使用 X 方式封锁
场景:完整的数据备份操作、特定的DDL操作等
b) 独占修改(EXCLUSIVE MODIFY),不允许其他事务修改对象,允许其他事务共享访问对象,使用 S + IX 方式封锁
场景:部分数据更新,修改表中一部份数据
c) 共享修改(SHARE MODIFY),允许其他事务共享修改对象,允许其他事务共享访问对象,使用 IX 方式封锁
场景:并发数据更新
d) 共享访问(SHARE ACCESS),允许其他事务共享修改对象,允许其他事务共享访问对象,使用 IS 方式封锁
场景:数据查询和分析、只读操作
4. 锁操作演示
查看锁的视图:
select *from V$LOCK;
ADDR 锁地址
TRX_ID 所属事务 ID
LTYPE 锁类型:TID 锁、对象锁
LMODE 锁模式:S 锁、X 锁、IX 锁、IS 锁
BLOCKED 是否阻塞。0 表示已上锁成功,非阻塞;1 表示处于上锁等待状态,阻塞
TABLE_ID 对于对象锁,表示表对象或字典对象的 ID;对于 TID 锁,表示封锁记录对应的表 ID。-1 表示事务启动封锁自身的 TID
ROW_IDX TID 锁封锁记录行信息。-1 表示事务启动封锁自身的 TID
TID TID 锁对象事务 ID
4.1 意向共享锁
操作select全表后,再查看锁

可以看到,事务号为339851的查询事务,对这张表添加了一个对象锁(OBJECT),并且锁的模式是意向共享锁(IS),BLOCKED=0,表示上锁成功
4.2 意向排它锁
操作insert操作后,再查看锁情况

可以看到insert操作,会对表添加IX锁 (IS为查询表锁视图加的)
4.3 排它锁
先执行update表操作,不提交
窗口1:
update test01 set A=3 where b=‘x’;
锁情况

窗口2:
alter table test01 add column C varchar ;

被阻塞
锁情况

可以看到,alter操作的X锁在等待状态,需要update提交后才能成功
如果update一直不提交,会出现alter操作等待超时,报错锁超时并回滚
4.4 TID锁
窗口1
update test01 set a=3 where b=‘x’;
不提交
查看锁情况

窗口2
update test01 set a=4 where b=‘x’;
查看锁情况

事务首先添加了一个对象锁IX,并未冲突
然后对同一行进行修改,则会出发TID锁(X锁),blocked=1,代表是上锁等待,锁对象为窗口1的事务号,这样,窗口2就知道该行数据正在被窗口1修改,需要等待窗口1完成修改后才能执行自己的修改操作。
提交窗口1后,再查看锁情况

blocked=0,上锁成功,事务语句可以执行
更多其他数据库相关专栏:
1.数据库优化
数据库优化基本思路、索引详解、执行计划、统计信息、CBO原理、单表优化、多表优化、分布式优化、子查询、优化案例等
数据库优化(sql优化)专栏连接
2.达梦分布式数据库:
部署详细步骤(DEM)、备份还原实战、核心特性理解、使用心得、表分区方式详细介绍、表分区最佳实践、DPC架构详解等
达梦分布式DPC专栏连接
3.应用开发类
jdbc、hibernate、ibatis、mybatis、MyBatis-Plus、Spring、中间件mycat、Sharding-JDBC等
达梦数据库应用开发专栏连接
2288

被折叠的 条评论
为什么被折叠?



