达梦数据库死锁
死锁
死锁是指两个或多个事务相互等待对方释放锁,形成了一个循环等待的情况.从而导致所有相关的事务都无法继续执行。在这种情况下,数据库会牺牲一个事务解除死锁,让另一个事务继续执行,而被牺牲的事务则需要回滚其操作。死锁通常都是由不合理的程序设计所导致。
阻塞
阻塞是指一个事务在请求某个资源的锁时,该资源已经被另一个事务占用,导致请求事务处于等待状态。直到占用锁的事务提交或回滚,阻塞的事务才能继续执行。
模拟测试
drop table IF EXISTS aaa;
CREATE table aaa (id int ,name varchar(10));
BEGIN
for i in 1..9 loop
insert into aaa values(i,'a'||i);
end loop;
end;
drop TABLE IF EXISTS bbb;
CREATE table bbb (id int ,name varchar(10));
BEGIN
for i in 1..9 loop
insert into bbb values(i,'b'||i);
end loop;
end;COMMIt;
--第一个窗口执行
BEGIN
UPDATE aaa set name='aaa' where id=1;
SLEEP(10);
UPDATE bbb set name='bbb' where id=1;
COMMIT;
end ;
--第二个窗口执行
BEGIN
UPDATE bbb set name='bb' where id=1;
UPDATE aaa set name='aa' where id=1;
COMMIT;
end ;
第一个窗口结果发生死锁

第二个窗口一直在执行中

原因分析:下图所示,步骤1和2的sql均能正常执行,当执行步骤3时,由于第2步没有提交,3需要等待2提交之后才能继续往下执行。而执行第4步时,由于第1步没有提交,4需要等待1结束才能继续执行。两个事务相互等待从而造成死锁,在报死锁错误的窗口执行回滚之后,第二个窗口会话立马执行完成。

--死锁可以通过V$DEADLOCK_HISTORY查询,
select * from V$DEADLOCK_HISTORY
打开四个窗口,分别执行上面4条语句,再打开一个窗口执行下面sql查询是否存在阻塞
方法一:
select *from v$sessions where trx_id in( SELECT WAIT_FOR_ID FROM V$TRXWAIT ) or trx_id in(SELECT id FROM V$TRXWAIT );

方法二:
select * from v$sessions s,v$lock l where s.trx_id=l.tid and l.blocked=1;

浙公网安备 33010602011771号