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

简介: 【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数据库会选择牺牲掉其中一个事务。

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


相关文章
|
7天前
|
SQL 数据库 开发者
达梦数据库 【-6111: 字符串转换出错】问题处理
在更新数据库某个值属性时,遇到了“字符串转换出错”的错误。经过分析,发现是由于 `id` 字段实际上是字符串类型而非数值类型导致的。最终通过将 `id` 的值改为字符串类型解决了问题。此问题提醒我们在处理数据库时要仔细检查表结构,不要凭经验臆断字段类型。
|
3月前
|
监控 Java 应用服务中间件
达梦数据库DEM监控部署教程分享
达梦数据库DEM监控部署教程分享
117 2
|
3月前
|
SQL 关系型数据库 MySQL
遇到mysql数据库死锁,你会怎么排查?
遇到mysql数据库死锁,你会怎么排查?
244 0
|
13天前
|
算法 安全 数据库
数据库死锁的解决方案有哪些?
【10月更文挑战第28天】数据库死锁是数据库管理中的一个常见问题
44 15
|
13天前
|
数据库连接 数据库 数据库管理
如何避免数据库死锁?
【10月更文挑战第28天】
38 14
|
21天前
|
关系型数据库 MySQL 数据库
一个 MySQL 数据库死锁的案例和解决方案
本文介绍了一个 MySQL 数据库死锁的案例和解决方案。
32 3
|
1月前
|
Oracle Java 关系型数据库
使用DataGrip链接达梦数据库
使用DataGrip链接达梦数据库
54 0
|
3月前
|
Oracle 关系型数据库 MySQL
Mysql和Oracle数据库死锁查看以及解决
【8月更文挑战第11天】本文介绍了解决MySQL与Oracle数据库死锁的方法。MySQL可通过`SHOW ENGINE INNODB STATUS`查看死锁详情,并自动回滚一个事务解除死锁;也可手动KILL事务。Oracle则通过查询V$LOCK与V$SESSION视图定位死锁,并用`ALTER SYSTEM KILL SESSION`命令终止相关会话。预防措施包括遵循ACID原则、优化索引及拆分大型事务。
126 3
|
3月前
|
Oracle 关系型数据库 Java
银河麒麟v10安装达梦数据库
银河麒麟v10安装达梦数据库
300 1
|
4月前
|
Oracle 关系型数据库 数据库
关系型数据库Oracle死锁
【7月更文挑战第16天】
69 3