1.定义

阻塞:多个线程之间的相互影响,等待临界资源; 

死锁:多个线程之间互相等待,形成等待环; 

对于死锁,达梦数据库会自动检测,并选择牺牲掉其中的一个事务,保证其它事务正常运行。 

select * from V$DEADLOCK_HISTORY;--查询死锁历史 

记录了产生死锁后被牺牲掉的事务的事务ID、会话ID、执行的SQL语句以及死锁发生时间(没有记录造成死锁的其它事务)。 

对于阻塞,达梦数据库不会自动处理,被阻塞的事务会一直挂起。应尽量形成短事务,快速提交。

2.阻塞排查

在达梦数据库中,查询永远不会被阻塞,SELECT FOR UPDATE的情况除外。 

INSERT语句被阻塞的情况:多个事务同时向有主键或唯一约束的表中插入相同的数据; 

删、改语句被阻塞的情况:所需要操作的数据被其它事务修改过,且一直没有提交或回滚

3.产生阻塞的原因

3.1环境创建

create table test(id int,name varchar);

 

insert into test values(1,'test1');

insert into test values(2,'test2');

insert into test values(3,'test3');

insert into test values(4,'test4');

insert into test values(5,'test5');

insert into test values(6,'test6');

insert into test values(7,'test7');

insert into test values(8,'test8');

insert into test values(9,'test9');

insert into test values(10,'test10');

commit;

 

3.2执行修改

update test set name='test222' where id=1;

 

3.3执行查询

select * from test where id=1;

 

3.4切换会话查询

 

由于之前的修改事务没有提交,所以新会话查出来的结果还是旧的值。

3.5在新会话执行删除操作

delete from test where id=1;

 

此时,发生阻塞,因为 delete 操作需要加锁,当前事务被挂起。

3.6在旧会话中查询阻塞的事务

 

事务13161被阻塞了,阻塞他的事务为13154,阻塞了148391毫秒。

之所以不在执行delete的会话中查,是因为那个会话卡主了,什么都做不了。

3.7通过 V$SESSIONS 视图查找两个事务对应的会话

select sess_id,sql_text,state,trx_id from v$sessions where trx_id in('13161','13154');

 

4. 阻塞的解决方法

根据需求,可以有两种解决方案。

4.1提交或回滚产生阻塞的事务

rollback;

commit;

4.2关闭产生阻塞的会话

使用系统过程 SP_CLOSE_SESSION(SESS_ID)来关闭对应的会话

 

SP_CLOSE_SESSION(2165133632)

https://eco.dameng.com/

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐