1. 程式人生 > >insert引起的死鎖

insert引起的死鎖

DEADLOCK DETECTED ( ORA-00060 )
[Transaction Deadlock]
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:
———Blocker(s)——– ———Waiter(s)———
Resource Name process session holds waits process session holds waits
TX-000a0002-00005420 68 440 X 65 496 S
TX-0001001b-00002b19 65 496 X 68 440 S
session 440: DID 0001-0044-000A2346 session 496: DID 0001-0041-000CBA54
session 496: DID 0001-0041-000CBA54 session 440: DID 0001-0044-000A2346
Rows waited on:
Session 496: obj – rowid = 00014282 – AAAUKCAAMAAAEZrAAA
(dictionary objn – 82562, file – 12, block – 18027, slot – 0)
Session 440: no row
Information on the OTHER waiting sessions:
Session 496:
pid=65 serial=58006 audsid=1896040 user: 88/VAS
O/S info: user: web_meg, term: unknown, ospid: , machine: ezg-web1
program: JDBC Thin Client
application name: JDBC Thin Client, hash value=2546894660
Current SQL Statement:
insert

 into TAB_XN_CONTENT_TEMP (key,content) values (:1,:2)
End of information on OTHER waiting sessions.
Current SQL statement for this session:
insert into TAB_XN_CONTENT_TEMP (key,content) values (:1,:2)

我一看到這個錯誤,有點不明白,oracle 的insert操作竟然導致表被鎖,然後查詢些資料終於有了眉目:
ORACLE執行insert等DML語句時,會首先自動在所要操作的表上申請一個TM鎖,當TM鎖獲得後,再自動申請TX型別的鎖。當兩個或多個會話在表的同一條記錄上執行DML語言時,第一個會話在記錄上加鎖,其它的會話處於等待狀態,一直到第一個會話提交後TX鎖釋放,其它的會話才可以加鎖。考慮是因為兩個insert

語句同時試圖向一個表中插入PK或unique值相同的資料,而造成其中會話被阻塞,等待其它會話提交或回滾,因而造成死鎖。這種情況,只要其中任何一個session提交,另外一個就會報出ORA-00001:違反唯一性約束條件,死鎖終止;或者其中一個session回滾,另外一個即可正常執行。
通過對這段話的理解,應該是一個會話插入了一條記錄未提交,然後另外一個會話繼續插入主鍵或者唯一索引列相同的記錄,導致死鎖的發生。

環境模擬:
在會話1中執行下面語句
CREATE TABLE t1(ID NUMBER);
ALTER TABLE t1 ADD primary key (ID);


INSERT INTO t1 VALUES(1);
INSERT

 INTO t1 VALUES(2);

然後在會話2中執行下面語句

INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(1);


通過上面模擬,重現了insert死鎖現象。

來源:http://www.xifenfei.com/2011/05/insert%E5%BC%95%E8%B5%B7%E7%9A%84%E6%AD%BB%E9%94%81.html