达梦数据库阻塞死锁及解锁

简介: 【10月更文挑战第6天】本文介绍了在达梦数据库中模拟和解决死锁的方法。首先通过创建表并插入数据但不提交事务,模拟了阻塞情况;接着利用V$TRXWAIT和V$SESSIONS视图查询阻塞信息,并通过SP_CLOSE_SESSION函数解决阻塞。最后讨论了死锁的成因及避免策略,强调了正确管理事务的重要性。

背景

最近在做的项目是银行的项目,由于现在的银行项目一般都要求数据库国产化,那么首选的国产化数据库就是达梦数据库了,在使用达梦数据库的时候,会遇到死锁的情况,那么遇到这种死锁情况该如何快速处理呢?今天主要先来模拟一下死锁,然后在解决死锁。可以让大家更直观的看到死锁的处理效果。

模拟阻塞产生

这里我在本地达梦数据库首先创建一个表,然后插入一条数据,但是不关闭查询框,不提交 COMMIT 事务。新建SQL查询语句窗口 A

CREATE TABLE TEST.TBL_TEST(ID INT PRIMARY KEY, NAME VARCHAR(50));
INSERT INTO TEST.TBL_TEST VALUES(1, '中文');

执行当前语句可以看到执行效果

image.png

再新建SQL查询语句窗口B,同时输入查询语句

INSERT INTO TEST.TBL_TEST VALUES(1, '中文');

执行语句可以看到如下的执行效果

image.png

这里显示【语句依次执行...】但是一直没有执行成功,其实就是对于主键约束字段,窗口A插入sql一直没有提交,窗口B再次插入相同主键数据时就会阻塞。

查询阻塞语句

这里通过 V$TRXWAIT 视图查看进程,找到ID,ID对应着V$SESSIONS视图的SESS_ID

select * from V$TRXWAIT ;

执行查询死锁语句后可以看到

image.png

其中:WAIT_FOR_ID 表示正在执行的事务ID,也就是说事务ID 12155 在等待 12154执行完成。

再通过V$SESSIONS视图,查找对应的ID号确定阻塞语句

SELECT SESS_ID,SQL_TEXT,TRX_ID from V$SESSIONS;

执行查询语句之后就可以看到具体的sql 阻塞内容

image.png

解决阻塞

解决阻塞其实也简单,当你找到需要解决的阻塞产生的SESS_ID了,你就可以调用 SP_CLOSE_SESSION(SESS_ID);系统函数来关闭会话

SP_CLOSE_SESSION(1866105112);
SP_CLOSE_SESSION(1859760408);

执行关闭回话系统函数之后,查看执行效果

image.png

再次查询产生阻塞产生的sql 内容查询语句

SELECT SESS_ID,SQL_TEXT,TRX_ID from V$SESSIONS;

可以看到刚才产生阻塞的两条语句已经没有了

image.png

那么到这里在遇到阻塞问题时的解决办法也就说完了,比较简单。当dm.ini中的参数ENABLE_MONITOR=1时,使用死锁历史动态试图V$DEADLOCK_HISTORY,可以查询到发生过的死锁信息。

SELECT * FROM V$DEADLOCK_HISTORY;

避免死锁

那么如何避免死锁呢,通常业务情况下,可能会出现这样的场景,比如数据库有两条数据,两个进程或者线程来操作这两条数据。首先查询数据表

SELECT * FROM TEST.TBL_TEST;

image.png

这时候你打开两个SQL查询窗口,在窗口A执行语句

UPDATE TEST.TBL_TEST SET NAME='1111' WHERE ID = 1;

在窗口B执行语句

UPDATE TEST.TBL_TEST SET NAME='2222' WHERE ID = 2;

在窗口A继续执行语句

UPDATE TEST.TBL_TEST SET NAME='2222' WHERE ID = 2;

在窗口B继续执行语句

UPDATE TEST.TBL_TEST SET NAME='1111' WHERE ID = 1;

此时可以看到窗口A的第二条更新语句一直显示 【语句正依次执行...】

image.png

而窗口B的第二条语句已经显示【死锁】了

image.png

死锁与阻塞的不同之处在于死锁包括两个或者多个已阻塞事务,它们之间形成了等待环,每个都等待其他事务释放锁。例如事务1给表T1上了排他锁,第二个事务给表T2上了排他锁,此时事务1请求T2的排他锁,就会处于等待状态,被阻塞。若此时T2再请求表T1的排他锁,则T2也处于阻塞状态。此时这两个事务发生死锁,DM数据库会选择牺牲掉其中一个事务。

死锁的本质也是锁等待,所以解决锁等待的问题,就解决了死锁的问题。


目录
打赏
0
1
1
0
1635
分享
相关文章
【赵渝强老师】达梦数据库的产品系列
达梦数据库是达梦公司推出的新一代自研数据库,融合分布式、弹性计算与云计算优势,支持超大规模并发事务处理和HTAP混合业务。产品体系包括DM8、DMDSC、DM DataWatch、DMMPP和DMRWC,分别适用于通用关系型数据库、共享存储集群、数据守护集群、大规模数据分析及读写分离场景,满足不同需求并保障高可用性和安全性。
90 36
达梦数据库 【-6111: 字符串转换出错】问题处理
在更新数据库某个值属性时,遇到了“字符串转换出错”的错误。经过分析,发现是由于 `id` 字段实际上是字符串类型而非数值类型导致的。最终通过将 `id` 的值改为字符串类型解决了问题。此问题提醒我们在处理数据库时要仔细检查表结构,不要凭经验臆断字段类型。
达梦数据库DEM监控部署教程分享
达梦数据库DEM监控部署教程分享
319 2
在云上轻松部署达梦数据库
达梦数据库(DM Database)是达梦数据库有限公司开发的关系型数据库管理系统,广泛应用于政府、金融、能源等行业。它具备高性能、高安全、兼容性强、易管理等特点,支持多种操作系统,适用于关键业务系统、政务系统及大数据处理等场景。在阿里云上,可通过一键部署快速使用达梦数据库DM8。
遇到mysql数据库死锁,你会怎么排查?
遇到mysql数据库死锁,你会怎么排查?
441 0
达梦数据库字段类型 varchar 转 text
本文介绍了在达梦数据库中将字段类型从 `varchar` 转换为 `text` 的两种方法:一是通过 DM数据迁移工具导出表结构和数据,修改后重新导入;二是通过添加临时字段、转移数据、删除原字段并重命名临时字段的方式实现转换。针对不同数据量的表,提供了灵活的解决方案。
数据库死锁的解决方案有哪些?
【10月更文挑战第28天】数据库死锁是数据库管理中的一个常见问题
194 15
一个 MySQL 数据库死锁的案例和解决方案
本文介绍了一个 MySQL 数据库死锁的案例和解决方案。
358 3
使用DataGrip链接达梦数据库
使用DataGrip链接达梦数据库
318 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等