Oracle
ORA-00060 |檢測到死鎖
我們在基於 Java/J2EE 的 Web 應用程序中遇到了 Oracle 死鎖 (ORA-00060) 問題。跟踪文件粘貼在下面:
以下死鎖不是 ORACLE 錯誤。這是由於使用者在應用程序設計中的錯誤或發出不正確的 ad-hoc SQL 而導致的死鎖。以下資訊可能有助於確定死鎖:
Deadlock graph: ---------Blocker(s)-------- ---------Waiter(s)--------- Resource Name process session holds waits process session holds waits TX-00030013-0000CC59-00000000-00000000 106 408 X 76 171 X TX-000F001E-0001681C-00000000-00000000 76 171 X 106 408 X session 408: DID 0001-006A-007D5293 session 171: DID 0001-004C-001C2F48 session 171: DID 0001-004C-001C2F48 session 408: DID 0001-006A-007D5293 Rows waited on: Session 408: obj - rowid = 0002A2AC - AAAqKsAAUAABE3oAAB (dictionary objn - 172716, file - 20, block - 282088, slot - 1) Session 171: obj - rowid = 0002A2AC - AAAqKsAAUAABE2pAAA (dictionary objn - 172716, file - 20, block - 282025, slot - 0) ----- Information for the OTHER waiting sessions ----- Session 171: sid: 171 ser: 62179 audsid: 1760178 user: ******* flags: (0x8000045) USR/- flags_idl: (0x1) BSY/-/-/-/-/- flags2: (0x40009) -/-/INC pid: 76 O/S info: user: ****, term: UNKNOWN, ospid: 48169 image: ************** client details: O/S info: user: ****, term: unknown, ospid: 1234 machine: ********* program: JDBC Thin Client client info: ********************* application name: JDBC, hash value=3519240545 action name: ProcessDummySearchData-UpdateSearchData, hash value=560080304 current SQL: UPDATE TABLE1 SET COL3=:1 ,LASTMODIFIED=SYSDATE WHERE UUID=:2 AND COL2=:3 ----- End of information for the OTHER waiting sessions ----- Information for THIS session: ----- Current SQL Statement for this session (sql_id=635v1mk350vst) ----- update TABLE1 set COL3= :1 where COL4= :2 and COL5 = :3
如果我嘗試從以下 URL 應用“建議的修復”:我不明白如何在 TABLE1 中創建複合索引 (UUID, COL2) & (COL4, COL5) 可以解決此問題?任何人都可以闡明如何解決這個問題嗎?我知道這個特定問題可能是由於同一表/行同時更新。
https://stackoverflow.com/questions/20474959/how-to-find-out-the-cause-of-an-oracle-deadlock
添加索引將減少發生死鎖的可能性,因為它可能消除掃描表的需要,但它並不能完全解決問題。問題是沒有什麼能強制 Oracle(或任何其他 RDMBS)在更新之前以任何保證的順序鎖定行。從死鎖跟踪中,您有 2 條語句同時執行並且似乎更新了相同的行:
---1 update TABLE1 set COL3= :1 where COL4= :2 and COL5 = :3 ; ----2 UPDATE TABLE1 SET COL3=:1 ,LASTMODIFIED=SYSDATE WHERE UUID=:2 AND COL2=:3;
有多種方法可以處理死鎖,其中一些:
1)在應用程序端擷取錯誤並重新執行失敗的更新。
2)
SELECT FOR UPDATE NOWAIT
在更新之前做(有或沒有SKIP LOCKED
)3)選擇您計劃在特定行中更新的行並
SELECT FOR UPDATE
單獨為每一行發布,然後更新行。4)
LOCK TABLE
在發布之前處於適當的模式update
- 在更新之前鎖定一些公共資源(例如你可能想要使用
DBMS_LOCK
函式)