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

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

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


相关文章
|
2月前
|
监控 Java 应用服务中间件
达梦数据库DEM监控部署教程分享
达梦数据库DEM监控部署教程分享
78 2
|
2月前
|
SQL 关系型数据库 MySQL
遇到mysql数据库死锁,你会怎么排查?
遇到mysql数据库死锁,你会怎么排查?
167 0
|
4天前
|
Oracle Java 关系型数据库
使用DataGrip链接达梦数据库
使用DataGrip链接达梦数据库
15 0
|
2月前
|
Oracle 关系型数据库 MySQL
Mysql和Oracle数据库死锁查看以及解决
【8月更文挑战第11天】本文介绍了解决MySQL与Oracle数据库死锁的方法。MySQL可通过`SHOW ENGINE INNODB STATUS`查看死锁详情,并自动回滚一个事务解除死锁;也可手动KILL事务。Oracle则通过查询V$LOCK与V$SESSION视图定位死锁,并用`ALTER SYSTEM KILL SESSION`命令终止相关会话。预防措施包括遵循ACID原则、优化索引及拆分大型事务。
|
2月前
|
Oracle 关系型数据库 Java
银河麒麟v10安装达梦数据库
银河麒麟v10安装达梦数据库
257 1
|
3月前
|
Oracle 关系型数据库 数据库
关系型数据库Oracle死锁
【7月更文挑战第16天】
50 3
|
4月前
|
SQL Java 数据库连接
使用Python通过JDBC操作数据库(达梦数据库)
使用Python通过JDBC操作数据库(达梦数据库)
623 0
|
4月前
|
Linux 数据库
Linux安装达梦数据库达梦数据
Linux安装达梦数据库达梦数据
|
4月前
|
SQL 存储 监控
达梦数据库死锁排查与解决
达梦数据库死锁排查与解决
1323 0
|
7天前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
37 6