關于J2EE中死鎖問題的研究(1)

大多數重要的應用程序都涉及高度并發性和多個抽象層。并發性與資源爭用有關,并且是導致死鎖問題增多的因素之一。多個抽象層使隔離并修復死鎖環境的工作變得更加困難。

  通常,當同時執行兩個或兩個以上的線程時,如果每個線程都占有一個資源并請求另一個資源,這時就會出現死鎖情況。因為如果一個線程不能獲取資源,則所有線程都不能繼續執行,我們稱那個特定的線程被阻塞;如果每個線程都由于同組中另一個線程所占有的資源而被阻塞,我們就稱這個線程組被死鎖。

  在本文中,我們將討論發生在典型的重要J2EE應用程序中的兩大類死鎖情況:“簡單”數據庫死鎖和跨資源死鎖。雖然我們的討論基于J2EE平臺,但也適用于其他技術平臺。

  數據庫死鎖

  在數據庫中,如果一個連接占用了另一個連接所需的數據庫鎖,則它可以阻塞另一個連接。如果兩個或兩個以上的連接相互阻塞,則它們都不能繼續執行,這種情況稱為死鎖。

  數據庫死鎖問題不易處理,這是因為涉及到的鎖定通常不是顯式的。通常,對數據行進行隱式更新時,需要鎖定該數據行,執行更新,然后在提交或回滾封閉事務時釋放鎖。由于數據庫平臺、配置的隔離級以及查詢提示的不同,獲取的鎖可能是細粒度或粗粒度的,它會阻塞(或不阻塞)其他對同一數據行、表或數據庫的查詢。

  獲取的鎖依賴于內部生成的查詢計劃。當數據大小和分步隨時間發生變化時,該計劃也可能改變。這樣在一個環境中獲取一組鎖的查詢可以嘗試在另一個環境中獲取一組完全不同的鎖。必要時,數據庫可以隨意地增加它的鎖。例如,數據庫可能會選擇鎖定整頁,而不是鎖定同一數據頁中的10個數據行,這會阻塞對無需鎖定的數據行的讀寫權限。

  基于數據庫模式,讀寫操作會要求遍歷或更新多個索引、驗證約束、執行觸發器等。每個要求都會引入更多鎖。此外,其他應用程序還可能正在訪問同一數據庫模式中的某些對象,并獲取不同于您的應用程序所具有的鎖。

  所有這些因素綜合在一起,數據庫死鎖幾乎不可能被消除了。值得慶幸的是,數據庫死鎖通常是可恢復的:當數據庫發現死鎖時,它會強制銷毀一個連接(通常是使用最少的連接),并回滾其事務。這將釋放所有與已經結束的事務相關聯的鎖,至少允許其他連接中有一個可以獲取它們正在被阻塞的鎖。

  由于數據庫具有這種典型的死鎖處理行為,所以當出現數據庫死鎖問題時,數據庫常常只能重試整個事務。當數據庫連接被銷毀時,會拋出可被應用程序捕獲的異常,并標識為數據庫死鎖情況。如果允許死鎖異常傳播到初始化該事務的代碼層之外,則該代碼層可以只啟動一個新事務并重做先前所有工作。要正確使用此策略,則在事務成功提交之前,它的代碼不能有其他操作。注意:要限制重試次數,否則易導致死鎖的代碼塊會永久循環下去。

  如果出現問題就重試,這種方法有點笨。但是,由于數據庫可以自由地獲取鎖,所以幾乎不可能保證兩個或兩個以上的線程不發生數據庫死鎖。此方法至少能保證在出現某些罕見的數據庫死鎖情況時,應用程序能正常運行。這比要求用戶去重試操作要好得多。

  在J2EE應用程序中,開發人員可以設置一個EJB調用以使用Bean托管事務(BMT)——開發人員啟動、提交或回滾特定的事務或容器托管事務(CMT)——調用方法前啟動事務,并在方法完成后提交或回滾事務。如果EJB供應商提供retry-on-deadlock參數,從而可以通過容器托管事務自動完成此操作,那當然再好不過了。如果沒有這種自動功能,開發人員最終將僅為了對死鎖進行重試而強制EJB調用使用Bean托管事務。

  遇到死鎖問題和鎖定其他線程的鎖的具體頻率在很大程度上取決于數據庫平臺、硬件、數據庫模式和查詢。在使用基于鎖的并發控制的數據庫(如MSSQL)中,未提交的寫操作會阻止讀操作,而未提交的讀操作會阻止寫操作,使數據庫更易出現死鎖問題。在多版本并發控制(MVCC)數據庫(如Oracle)中,未提交的寫操作不阻止讀操作——讀操作僅查看舊版本數據行。這雖然會引入其他問題,但不會造成同樣多的死鎖機會。我們要讓自己熟悉這些數據庫鎖定模式,并注意自己正在使用的類型。

  在查找、修復以及避免數據庫死鎖方面,有一些很好的參考方法,但它們都不能徹底消除死鎖的可能性。

  跨資源死鎖

  當死鎖情況不完全局限于數據庫時,將更難找到它。數據庫對占有和請求的鎖有識別能力,所以能檢測整個數據庫中的死鎖;此外,數據庫事務在確定哪些東西是原子、哪些不是方面提供了一個良好的界線,所以能輕松地回滾事務,使其從死鎖中恢復。其他環境(如Java虛擬機)中的死鎖或可跨環境的死鎖更加危險,因為環境不能(或沒有)檢測到這些死鎖并嘗試恢復。更糟糕的是,這些死鎖會產生綜合效果——如果兩個線程占有某些資源集時出現死鎖,則其他任何嘗試訪問其中一個資源的線程也將被阻塞,該線程已經獲取的所有資源也被阻塞。這些死鎖常常不易發現,但對常見模式有一定的了解將有助于識別和修復死鎖問題。

  當環境中出現可疑的死鎖情況時,您就需要考慮一些問題了。這些問題的答案將說明您正在處理的情形是下列情形中的哪一種(如果有的話),并提供了修復以下問題的詳細信息。要考慮的一些重要事項包括:
  • 涉及什么線程,它們的調用堆棧是什么?這需要進行一些詳細的分析,將實際的死鎖線程從那些只是被死鎖的線程阻塞了的線程中分離出來。
  • 這種死鎖情況總是在特定的代碼路徑中出現(每次執行這些特定的操作時),還是依賴于兩個或兩個以上同時執行的代碼路徑呢?
  • 涉及的數據庫連接是什么?每個連接占有的數據庫鎖是什么?每個連接嘗試獲取的數據庫鎖是什么?每個數據庫連接響應的Java虛擬機線程是什么?
  下一小節介紹了三種常見的發生跨資源死鎖的情形。

轉載于:https://www.cnblogs.com/xiefang1980/archive/2008/04/28/1174130.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/380050.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/380050.shtml
英文地址,請注明出處:http://en.pswp.cn/news/380050.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python變量分配內存_Python | 聲明任何變量而不分配任何值

python變量分配內存Since, Python is a dynamic programming language so there is no need to declare such type of variable, it automatically declares when first time value assign in it. 由于Python是一種動態編程語言,因此無需聲明此類變量,它…

UVA 10004 - Bicoloring

模擬染色&#xff0c;因為只有兩種顏色&#xff0c;所以分別用 0、 1 代表這兩種顏色&#xff0c;然后從0開始深搜&#xff0c;如果 每個點都能染上色&#xff0c;且相鄰兩點的顏色不同&#xff0c;則符合要求。 #include<stdio.h>#include<string.h>#define MAXN …

標志寄存器:CF、PF、AF、ZF、SF、TF、DF、OF

注&#xff1a;下面說到的標志寄存器都是縮寫&#xff0c;C就是CF&#xff0c;其他也一樣 標志寄存器&#xff1a;C、P、A、Z、S、T、D、O的內容只會是0或1&#xff0c;0表示假&#xff0c;1表示真 O&#xff1a;溢出標志 一個寄存器如果存放的值超過所能表示的范圍&#xf…

揭秘:銷售人員26個致命弱點

銷售人員有許多積極的態度需要學習&#xff0c; 同時也有許多不良的習慣應該避免&#xff0c;以免影響個性及專業能力。仔細看看這些缺點&#xff0c;反省你自己&#xff0c;還需要改善的畫&#xff0c;直到你給自己一百分為止。找一位深知你的好 友&#xff0c;讓他誠實地給你…

Java——集合(練習題)

例題1&#xff1a;產生10個1~20之間的隨機數&#xff0c;要求隨機數不能重復 import java.util.HashSet; import java.util.Random; public class Test1 {/*** 產生10個1~20之間的隨機數&#xff0c;要求隨機數不能重復* * 分析&#xff1a;* 1,有Random類創建隨機數對象* 2&a…

模塊化 組件化 工程化_軟件工程中的模塊和軟件組件

模塊化 組件化 工程化The module in software is a small part of the software that is responsible for performing any kind of functionality. Sometimes, the term sub-program is also used to refer to the term module. 軟件中的模塊是軟件的一小部分&#xff0c;負責…

Firefox2狂占CPU解決辦法

https://images.cnblogs.com/cnblogs_com/Tisty/138006/o_firefox3.jpg 看了一下&#xff0c;不知道 "jpeg_free_large" 是干啥的&#xff0c;遂用 "Firefox jpeg_free_large" Google 一下&#xff0c;出來的一堆東西里有帖子說可能和 Apple 的 QuickTime …

PUSHAD和POPAD,以及PUSHA和POPA

PUSHAD PUSHAD也叫保護現場&#xff0c;就是把我們的寄存器壓入棧中 pushad是把eax&#xff0c;ecx&#xff0c;edx&#xff0c;ebx&#xff0c;esp、ebp&#xff0c;esi&#xff0c;edi依次壓入棧中&#xff0c;ESP會減少32&#xff0c;相當于&#xff1a; push eax push ec…

Java——n個數的全排列

例題&#xff1a; 輸入一串字符串&#xff0c;將該字符串中的字符元素進行全排列&#xff0c;然后&#xff0c;一串輸出結果。 例如&#xff1a; 輸入&#xff1a; ABCD 輸出&#xff1a; ABCD ABDC ACBD ACDB ADBC ADCB BACD BADC BCAD BCDA BDAC BDCA CABD CADB CBAD CBDA…

一段個性化stringgrid的代碼

需要注意的是 該段程序使用了 canvas。 procedure TW_CkbTaiZhang.KhLstDrawCell(Sender: TObject; ACol,ARow: Integer; Rect: TRect; State: TGridDrawState);begin if ARowkhlst.Row then with khlst.Canvas do //畫 cell 的邊框 begin Pen.Color : $00ff0000; …

dp 扔雞蛋_使用動態編程(DP)的雞蛋掉落問題

dp 扔雞蛋Problem statement: You are given N floor and K eggs. You have to minimize the number of times you have to drop the eggs to find the critical floor where critical floor means the floor beyond which eggs start to break. Assumptions of the problem: 問…

MOVSX和MOVZX

MOVSX 先符號擴展,再傳送 格式&#xff1a; MOVSX 操作數A &#xff0c;操作數B //操作數B的空間小于A比如說我們使用命令&#xff1a; movsx eax&#xff0c;bxbx是16位&#xff0c;eax是32位&#xff0c;傳值過程&#xff1a; 先用bx的符號位把eax高16填滿&#xff0c;b…

統計學習以及支持向量機的國內外基本比較重要的書

1、支持向量機導論&#xff0c;此書乃是SVM方面的經典著作&#xff0c; 該書的作者也是近年來SVM、kernel methods學術圈內的活躍學者&#xff0c;對于這些領域均有過重要的貢獻。這本書從“線性機器、核方法、統計學習理論、凸優化”四個方面揭示了SVM的內在機理 --利用核…

Java——集合(TreeSet)

package com.wsq.set; //這里進行調用Person()方法&#xff0c;要進行導包 import java.util.TreeSet; import com.wsq.bean.Person; public class Demo3_TreeSet { /*** TreeSet集合是用來對元素進行排序的&#xff0c;同樣它也可以保證元素的唯一* 當compareTo()方法返…

setmonth_日期setMonth()方法以及JavaScript中的示例

setmonthJavaScript日期setMonth()方法 (JavaScript Date setMonth() method) setMonth() method is a Date class method, it is used to set the month to the Date object with a valid month value (between 0 to 11. 0 for January, 1 for February and so on). setMonth(…

LEA與XCHG

LEA 格式&#xff1a; LEA 通用寄存器 內存地址功能&#xff1a;取地址命令 將內存地址賦值給寄存器 lea eax,dword ptr ds:[ecx0x16]dword 雙字 就是四個字節ptr pointer縮寫 即指針ds 數據段版寄存器[]里的數據是一個地址值&#xff0c;這個地址指向一個雙字型數據 將dwo…

分域名優化的時候要考慮備選IP的問題

我們在需要下載很多內容的時候&#xff0c;很容易想到做分域名的并發下載&#xff0c;給原來的服務器多分幾個域名&#xff0c;因為分不同的域名可能可以在瀏覽器中分到更多的下載進程&#xff0c;提高下載速度。 但是在做網絡應用的時候&#xff0c;我們的一個域名下面有的時候…

面試題-ASP 與 ASP.Net的區別?

比較簡潔的回答&#xff1a; 1.開發語言不同&#xff0c;ASP局限于用腳本語言來開發&#xff0c;而ASP.Net可以使用C#,VB.C等來開發。 2.運行機制不同&#xff0c;ASP是解釋運行的&#xff0c;執行效率較低。ASP.Net是編譯性的編程框架。 3.開發方式不同&#xff0c;ASP里前臺H…

Java——集合(輸入5個學生的信息按總分高低排序)

題目要求&#xff1a; 鍵盤錄入5個學生信息&#xff08;姓名&#xff0c;語文成績&#xff0c;數學成績&#xff0c;英語成績&#xff09;&#xff0c;按照總分從高到低輸出到控制臺 分析&#xff1a; 1&#xff0c;定義一個學生類 * 成員變量&#xff1a;姓名&#xff0c;…

日期setHours()方法以及JavaScript中的示例

JavaScript Date setHours()方法 (JavaScript Date setHours() method) setHours() method is a Date class method, it is used to set the hour to the Date object with a valid hour value (between 00 to 23). setHours()方法是Date類方法&#xff0c;用于將小時設置為具有…