2014-03-03 66 views
0

我得到的僵局,同時運行下面的查詢在Oracle中死鎖在甲骨文

update MYTABLE 
    set COLUMN1 = COLUMN1 + 589 
where COLUMN1 >= 7988 
    and COLUMN1 <= 7988 

update MYTABLE 
    set COLUMN1 = COLUMN1 + 660 
where COLUMN1 >= 7840 

爲什麼我會得到一個僵局當這兩個查詢在兩個獨立的事務運行? 我的觀點是第二個查詢將等到第一個查詢完成其事務時隔離被設置爲READCOMMITTED對不對?

有沒有我可以申請避免死鎖的提示?

注:COLUMN1是不是在該表中的PK,但是應用程序可確保有沒有重複。

回答

2

由於兩個窗口都重疊,我認爲可能存在這個問題。 Oracle爲這兩個查詢鎖定相同的塊,因此在同時執行時出現問題。

另外,檢查answer in this question上左右。

檢查上有鎖時通過檢查dba_lock表。請參閱文檔here

+1

但是,如果第一個事務鎖定了整個表,那麼第二個事件會不會阻塞,直到第一個事務釋放這些鎖? –

+0

@AlexPoole:我認爲你是對的,除非Oracle在塊級鎖定。 –

+0

不,帕特里克,在這種情況下('where where子句存在),整個表將不會被鎖定,只有行的子集將會是。其次,在這種情況下,存在或不存在索引不會有助於避免死鎖(當表與外鍵列上創建的索引之間存在主\明細關係時,存在索引可能會有所幫助) –

2

是的,你提出的這些陳述可能會產生死鎖。最簡單的情況之一是:

  1. 第1次會議首先發出update聲明;
  2. 第二部分發布第二個update聲明;
  3. 第一部分發布第二個update聲明;

例子:

-- Session #1 locks a subset of rows 
SQL> update mytable 
     set column1 = column1 + 589 
     where column1 >= 7988 
     and column1 <= 7988; 

1 row updated. 

              -- session #2 
              -- trying to lock subset of rows 
              -- locked by the first session update 
              SQL> update mytable 
                set column1 = column1 + 660 
               where column1 >= 7840; 


-- session #1 
-- trying to lock subset of rows that are locked 
-- by session #2 update, that in turn's 
-- trying to lock the subset of rows 
-- locked by session #1 update statement 
SQL> update mytable 
     set column1 = column1 + 660 
     where column1 >= 7840; 


              -- session #2 
              -- thus deadlock 
              update mytable 
               set column1 = column1 + 660 
              where column1 >= 7840 
                   * 
              ERROR at line 1: 
         ORA-00060: deadlock detected while waiting for resource 

當你構建使用where子句updatedelete語句,該語句變成包括閱讀和寫作部分由兩部分組成的語句。閱讀部分保留行for update並寫一個更改它們。因此,第一屆會議的update聲明鎖住更新一些數據集,改變它們並保持鎖定狀態,直到發出commitrollback,第二屆會議的update聲明鎖定行的一部分,他們第一次會議是試圖鎖定數據的的一部分,這是被第二個鎖定,從而陷入僵局。如果您在一個會話中發佈這些更新語句,則不應該有任何死鎖。但是,如果您在多個會話中同時發出這些更新語句而沒有提交或回滾,請爲ORA-00060異常做好準備。

每個死鎖都伴隨着警報文件的創建。檢查文件以獲取有關死鎖的更多詳細信息。

有沒有我可以申請以避免死鎖任何暗示?

沒有,有沒有這樣的提示。