如何在Oracle中生成死锁方案?

时间:2019-09-01 08:24:50

标签: oracle plsql transactions

在过去的四个小时中,我一直困扰于实验室问题,因为即使进行了广泛的研究并翻阅了无数幻灯片,我通常也不知道它想要什么。编辑有问题的序言是一个dbcreate.sql,它将创建一系列表,然后是dbload.sql,它将值插入给定表中。

给定的问题是

  

在PL / SQL中实现对在Prologue步骤中创建的示例数据库进行操作的数据库事务,并使其并发处理导致daadadlock情况。将事务保存在SQL脚本solution1-1.sql和solution1-2.sql

我觉得这个网站上的某人可以用我能理解的方式来解释这一点!谢谢您的帮助

编辑此问题的第二部分

  

模拟事务的并发处理,这样将导致死锁。   要模拟数据库事务的并发处理,请使用PL / SQL过程   从标准PL / SQL包DBMS_LOCK休眠。通过“并发模拟   执行”是指第一个事务做了一些工作,然后延迟了一个   在一定时间段内,并且在同一时间段内处理另一笔交易。   最后,在延迟之后,第一笔交易完成了其工作。

2 个答案:

答案 0 :(得分:3)

最简单的方法(未经测试的代码):

CREATE OR REPLACE PROCEDURE doUpd ( id1 IN NUMBER, id2 IN NUMBER ) IS
BEGIN
   UPDATE tableA set colA = 'upd1' where id = id1;
   dbms_lock.sleep (20);
   UPDATE tableA set colA = 'upd2' where id = id2;
END;
/

然后在会话1中运行:

execute doUpd( 21, 12 );

立即进入会话2:

execute doUpd( 12, 21 );

我们正在做的是更新2行,但是顺序不同。 我们希望两次更新之间的时间间隔足够小,以免造成僵局。但是,如果要模拟死锁,则需要添加延迟,以便可以在另一个会话中触发更新。

在上面的示例中,会话1将更新ID = 21的行,然后等待20秒,然后更新ID 12的行。

会话2将更新ID = 12的行,然后等待20秒,然后更新ID 21的行。如果会话2在会话1处于“睡眠”状态时开始,则应该出现死锁。

按时间顺序,只要您可以快速开始第2阶段的工作,就应该针对以下目标:

会议1:UPDATE tableA set colA = 'upd1' where id = 21;

会议1:sleep 20

会议2:UPDATE tableA set colA = 'upd1' where id = 12;

会议2:sleep 20

会话1:UPDATE tableA set colA = 'upd2' where id = 12;-被阻止,直到会话2提交/回滚

会话2:UPDATE tableA set colA = 'upd2' where id = 21;-被阻止,直到会话1提交/回滚

会话1和2现在已死锁。

答案 1 :(得分:0)

对于问题的第一部分,您也可以使用不带DBMS_LOCK软件包的以下示例:

CREATE TABLE T1 (c INTEGER, v INTEGER);
INSERT INTO T1 VALUES (1, 10);
INSERT INTO T1 VALUES (2, 10);
COMMIT;
  1. 公开会议1
  2. 公开会议2
  3. 在会话1中执行update t1 set v = v + 10 where c = 1;
  4. 在会话2中,执行update t1 set v = v + 10 where c = 2;
  5. 在会话1中执行update t1 set v = v + 10 where c = 2;
  6. 在会话2中,执行update t1 set v = v + 10 where c = 1;
  7. 会议1引发ORA-00060: deadlock detected while waiting for resource