两个会话相互阻塞,这两个会话都被挂起,每个会话都在等待另一个会话释放其锁定,这种场景被称为死锁(deadlock).死锁不是DBA的问题,而是由不恰当的程序设计导致,主要是请求锁定的顺序问题,并且数据库自身能够自动解决死锁问题。
-- 先建立一个表,写入资料
CREATE TABLE RESOURCES(
RESOURCE_CODE VARCHAR2(10),
RESOURCE_DESC VARCHAR2(50),
ACCESS_TIME DATE,
CONSTRAINT PK_RESOURCES PRIMARY KEY (RESOURCE_CODE)
USING INDEX
);
INSERT INTO RESOURCES VALUES('RES_A','Resource A',SYSDATE);
INSERT INTO RESOURCES VALUES('RES_B','Resource B',SYSDATE);
COMMIT;
-- 在两个不同的Session中按顺序执行以下语句
-- Session1 Session2
-- ------------------------------ ------------------------------
-- Session1更改RES_A, RES_A被Session1锁定, 其他Session要更改需要等待.
UPDATE RESOURCES
SET ACCESS_TIME = SYSDATE
WHERE RESOURCE_CODE = 'RES_A';
-- Session2更改RES_B, RES_B被Session2锁定, 其他Session要更改需要等待.
UPDATE RESOURCES
SET ACCESS_TIME = SYSDATE
WHERE RESOURCE_CODE = 'RES_B';
-- Session1执行更改时处于等待状态,因Session2已锁定RES_B
UPDATE RESOURCES
SET ACCESS_TIME = SYSDATE
WHERE RESOURCE_CODE = 'RES_B';
-- Session2执行更改时处于等待状态,因Session1已锁定RES_A
UPDATE RESOURCES
SET ACCESS_TIME = SYSDATE
WHERE RESOURCE_CODE = 'RES_A';
-- Session1检测到死锁: 因Session1与Session2均持有对方需要的资源
-- ORA-00060: deadlock detected while waiting for resource
-- Session2继续等待RES_A
-- 因Session1检测到错误一般需要回滚
-- Session1回滚,释放锁定资源
ROLLBACK;
-- Session2执行更改RES_A成功
COMMIT;
可以看出,出现死锁后先等待资源的Session先出现错误信息
出现死锁一般是由于对业务逻辑处理不规范所致,如上,对于一组资源(RES_A,RES_B)的处理,Session1与Session2出现不同的处理顺序,则可能出现死锁。