在过去的四个小时中,我一直困扰于实验室问题,因为即使进行了广泛的研究并翻阅了无数幻灯片,我通常也不知道它想要什么。编辑有问题的序言是一个dbcreate.sql,它将创建一系列表,然后是dbload.sql,它将值插入给定表中。
给定的问题是
在PL / SQL中实现对在Prologue步骤中创建的示例数据库进行操作的数据库事务,并使其并发处理导致daadadlock情况。将事务保存在SQL脚本solution1-1.sql和solution1-2.sql
中
我觉得这个网站上的某人可以用我能理解的方式来解释这一点!谢谢您的帮助
编辑此问题的第二部分
模拟事务的并发处理,这样将导致死锁。 要模拟数据库事务的并发处理,请使用PL / SQL过程 从标准PL / SQL包DBMS_LOCK休眠。通过“并发模拟 执行”是指第一个事务做了一些工作,然后延迟了一个 在一定时间段内,并且在同一时间段内处理另一笔交易。 最后,在延迟之后,第一笔交易完成了其工作。
答案 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;
update t1 set v = v + 10 where c = 1;
update t1 set v = v + 10 where c = 2;
update t1 set v = v + 10 where c = 2;
update t1 set v = v + 10 where c = 1;
ORA-00060: deadlock detected while waiting for resource