事物A和事物B發生死鎖,其中一個事物(假設A)探測到死鎖,Oracle將會做如下動作:
(1) 事物A將拋出ORA-00060異常并回滾最後一條SQL語句;
(2) 事物B繼續執行;
如果應用程式沒有對事物異常進行捕獲并Rollback,那么事物A將會出現數據不一致的情況!
測試如下:
1. 創建測試表:
CREATE TABLE DBATEST.DBA_TAB_1
(
CODE VARCHAR2(20 BYTE),
ADD_DATE DATE,
QTY_1 NUMBER,
QTY_2 NUMBER
)
TABLESPACE D_DBA_TEST;
2. 插入測試數據:
BEGIN
INSERT INTO DBATEST.DBA_TAB_1 VALUES('AAA', SYSDATE, 0, 0);
INSERT INTO DBATEST.DBA_TAB_1 VALUES('BBB', SYSDATE, 0, 0);
COMMIT;
END;
/
3. 第一個session執行如下操作:
SQL> UPDATE DBATEST.DBA_TAB_1 SET QTY_1 = QTY_1 + 1 WHERE CODE = 'AAA';
1 row updated.
4. 第二個session執行如下操作:
SQL> UPDATE DBATEST.DBA_TAB_1 SET QTY_2 = QTY_2 + 1 WHERE CODE = 'BBB';
1 row updated.
5. 第一個session執行如下操作:
SQL> UPDATE DBATEST.DBA_TAB_1 SET QTY_1 = QTY_1 + 1 WHERE CODE = 'BBB';
6. 第二個session執行如下操作:
SQL> UPDATE DBATEST.DBA_TAB_1 SET QTY_2 = QTY_2 + 1 WHERE CODE = 'AAA';
7. 第一個session探測到死鎖,并拋出以下異常:
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
8. 第二個session中的兩條update語句成功執行;
9. 在第一個和第二個session中執行commit
10. 查看數據:
CODE ADD_DATE QTY_1 QTY_2
---- ------------------- ---------- ----------
AAA 2013-07-30 21:16:01 1 1
BBB 2013-07-30 21:16:07 0 1
分析數據可以發現:
第一個session:
UPDATE DBATEST.DBA_TAB_1 SET QTY_1 = QTY_1 + 1 WHERE CODE = 'AAA'; --更新成功
UPDATE DBATEST.DBA_TAB_1 SET QTY_1 = QTY_1 + 1 WHERE CODE = 'BBB';
-- 更新失敗,探測到死鎖后,此語句rollback
第二個session:
UPDATE DBATEST.DBA_TAB_1 SET QTY_2 = QTY_2 + 1 WHERE CODE = 'BBB';
-- 更新成功
UPDATE DBATEST.DBA_TAB_1 SET QTY_2 = QTY_2 + 1 WHERE CODE = 'AAA';
-- 更新成功
解決辦法:
當第一個session探測到死鎖后,執行rollback
(1) 事物A將拋出ORA-00060異常并回滾最後一條SQL語句;
(2) 事物B繼續執行;
如果應用程式沒有對事物異常進行捕獲并Rollback,那么事物A將會出現數據不一致的情況!
測試如下:
1. 創建測試表:
CREATE TABLE DBATEST.DBA_TAB_1
(
CODE VARCHAR2(20 BYTE),
ADD_DATE DATE,
QTY_1 NUMBER,
QTY_2 NUMBER
)
TABLESPACE D_DBA_TEST;
2. 插入測試數據:
BEGIN
INSERT INTO DBATEST.DBA_TAB_1 VALUES('AAA', SYSDATE, 0, 0);
INSERT INTO DBATEST.DBA_TAB_1 VALUES('BBB', SYSDATE, 0, 0);
COMMIT;
END;
/
3. 第一個session執行如下操作:
SQL> UPDATE DBATEST.DBA_TAB_1 SET QTY_1 = QTY_1 + 1 WHERE CODE = 'AAA';
1 row updated.
4. 第二個session執行如下操作:
SQL> UPDATE DBATEST.DBA_TAB_1 SET QTY_2 = QTY_2 + 1 WHERE CODE = 'BBB';
1 row updated.
5. 第一個session執行如下操作:
SQL> UPDATE DBATEST.DBA_TAB_1 SET QTY_1 = QTY_1 + 1 WHERE CODE = 'BBB';
6. 第二個session執行如下操作:
SQL> UPDATE DBATEST.DBA_TAB_1 SET QTY_2 = QTY_2 + 1 WHERE CODE = 'AAA';
7. 第一個session探測到死鎖,并拋出以下異常:
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
8. 第二個session中的兩條update語句成功執行;
9. 在第一個和第二個session中執行commit
10. 查看數據:
CODE ADD_DATE QTY_1 QTY_2
---- ------------------- ---------- ----------
AAA 2013-07-30 21:16:01 1 1
BBB 2013-07-30 21:16:07 0 1
分析數據可以發現:
第一個session:
UPDATE DBATEST.DBA_TAB_1 SET QTY_1 = QTY_1 + 1 WHERE CODE = 'AAA'; --更新成功
UPDATE DBATEST.DBA_TAB_1 SET QTY_1 = QTY_1 + 1 WHERE CODE = 'BBB';
-- 更新失敗,探測到死鎖后,此語句rollback
第二個session:
UPDATE DBATEST.DBA_TAB_1 SET QTY_2 = QTY_2 + 1 WHERE CODE = 'BBB';
-- 更新成功
UPDATE DBATEST.DBA_TAB_1 SET QTY_2 = QTY_2 + 1 WHERE CODE = 'AAA';
-- 更新成功
解決辦法:
當第一個session探測到死鎖后,執行rollback
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26156924/viewspace-767507/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/26156924/viewspace-767507/