數據庫事務 - 怎樣才能產生 互相等待 - 死鎖,怎么解決


數據庫事務 - 怎樣才能產生 互相等待 - 死鎖,如何解決

1. 最簡單的死鎖

    最常見的死鎖 是因為一個事務執行時間過長,而導致另外一個事務 無法 訪問 被被該事務鎖定的資源,最終 超時 而導致的死鎖異常.  這種情況無非有兩種解決方案,一是性能調優。 二是當該事務遇到等待超時導致的死鎖異常后,繼續讓該事務 re-try.

 

2. 互相等待 -- 死鎖

    這種 死鎖的異常情況特殊,兩個極短的事務 在 高並發的環境下也可能發生 相互等待 -- 死鎖 的情況.

    a) 怎樣導致的?

        總的來說,是因為兩個事務 對共有資源的CUD 執行順序 不同導致的. 如下,

        事務1:  A  -- >  B

        事務2:  B  -- >  A

        在高並發情況下,如果 相同時間內,事務1 處理完 對資源A的CUD 同時 事務2 處理完 對資源B 的CUD。 這個時候 事務1 要對 B 資源 CRUD 同時 事務2也要對 A資源 CRUD, 而此時, 事務1 鎖住了A資源,事務2鎖住了B資源,所以 事務1需要等待事務2釋放B資源 才能繼續對B資源操作,相反事務2需要等待事務1釋放A資源 才能繼續對A資源操作。 這樣 兩個事務互相等待 鎖釋放 而導致死鎖         

 

 

    b) 如何解決?    

        唯一的辦法就是 讓這兩個事務 對共有資源的CUD 執行順序 一樣。

        事務1:  A  -- >  B

        事務2:  A  -- >  B

       

        有趣的問題 如果事務2 是 A --> B --> A   而事務1保持不變, 當事務2 執行完B資源操作 再次對A資源操作的時候 會不會出現死鎖呢, 看起來如果事務1同時也執行到對B資源操作的時候 - 好像會, 但答案是不會.  
        原因很簡單,因為 A資源已經被 事務2 鎖定, 事務1 不會有機會啟動,只有等待 事務2 釋放 A資源鎖后,得到該鎖的事務1才能開始執行。

 

        同樣, 如果我們 這樣設定執行的順序來解決這樣的問題,是不是會導致 線程相互等待的時間過長 而導致性能大幅降低呢 ?( 如事務2 先執行,那么事務1就必須等待 事務2執行完后,釋放對A 資源的鎖后, 得到該鎖的事務1 才能繼續執行)
        我們完全沒必要有這種擔憂, 原因很簡單,大型系統中, 即便是在高並發狀態下,兩個或者多個不同線程的事務 能同時在千萬條數據中 並發訪問到(這里指 CUD 操作)完全相同的數據 的概率是相當小的 。

               

 

 產生死鎖的必要條件   雖然進程在運行過程中,可能發生死鎖,但死鎖的發生也必須具備一定的條件,死鎖的發生必須具備以下四個必要條件 。

  1 )互斥條件: 指進程對所分配到的資源進行排它性使用,即在一段時間內某資源只由一個進程占用。如果此時還有其它進程請求資源,則請求者只能等待,直至占有資源的進程用畢釋放。

  2 )請求和保持條件: 指進程已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它進程占有,此時請求進程阻塞,但又對自己已獲得的其它資源保持不放。

  3 )不剝奪條件: 指進程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。(既是沒有Timeout 或者 更高優先級剝奪 的情況) 

  4 )環路等待條件: 指在發生死鎖時,必然存在一個進程——資源的環形鏈,即進程集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1占用的資源;P1正在等待P2占用的資源,……,Pn正在等待已被P0占用的資源。

 

      死鎖的詳細說明

 

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM