日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Java程序中解決數(shù)據(jù)庫超時與死鎖

Java程序中解決數(shù)據(jù)庫超時與死鎖,每個使用關系型數(shù)據(jù)庫的程序都可能遇到數(shù)據(jù)死鎖或不可用的情況,而這些情況需要在代碼中編程來解決;本文主要介紹與數(shù)據(jù)庫事務死鎖等情況相關的重試邏輯概念,此外,還會探討如何避免死鎖等問題,文章以DB2(版本9)與Java為例進行講解。

簡介

每個使用關系型數(shù)據(jù)庫的程序都可能遇到數(shù)據(jù)死鎖或不可用的情況,而這些情況需要在代碼中編程來解決;本文主要介紹與數(shù)據(jù)庫事務死鎖等情況相關的重試邏輯概念,此外,還會探討如何避免死鎖等問題,文章以DB2(版本9)與Java為例進行講解。

什么是數(shù)據(jù)庫鎖定與死鎖

鎖定(Locking)發(fā)生在當一個事務獲得對某一資源的“鎖”時,這時,其他的事務就不能更改這個資源了,這種機制的存在是為了保證數(shù)據(jù)一致性;在設計與數(shù)據(jù)庫交互的程序時,必須處理鎖與資源不可用的情況。鎖定是個比較復雜的概念,仔細說起來可能又需要一大篇,所以在本文中,只把鎖定看作是一個臨時事件,這意味著如果一個資源被鎖定,它總會在以后某個時間被釋放。而死鎖發(fā)生在當多個進程訪問同一數(shù)據(jù)庫時,其中每個進程擁有的鎖都是其他進程所需的,由此造成每個進程都無法繼續(xù)下去。

如何避免鎖

我們可利用事務型數(shù)據(jù)庫中的隔離級別機制來避免鎖的創(chuàng)建,正確地使用隔離級別可使程序處理更多的并發(fā)事件(如允許多個用戶訪問數(shù)據(jù)),還能預防像丟失修改 (Lost Update)、讀“臟”數(shù)據(jù)(Dirty Read)、不可重復讀(Nonrepeatable Read)及“虛”(Phantom)等問題。

在只讀模式中,就可以防止鎖定發(fā)生,而不用那些未提交只讀隔離級別的含糊語句。一條SQL語句當使用了下列命令之一時,就應該考慮只讀模式了:

1、JOIN

2、SELECT DISTINCT

3、GROUP BY

4、ORDER BY

5、UNION

6、UNION ALL

7、SELECT

8、FOR FETCH ONLY (FOR READ ONLY)

9、SELECT FROM

如果包含上述任一命令,可以說你的SQL語句有歧義性,因此,鎖可能就是造成其中資源問題的源頭。

另外,以下是一些可降低鎖數(shù)目的建議:

1、 將CURRENTDATA設為NO。這條命令告訴DB2模糊光標為只讀。

2、 在適當?shù)臅r候,盡可能使用User Uncommitted Read(用戶未提交的讀)。

3、 盡可能關閉所有光標。

4、 有一個正確的提交策略。確保程序不再使用資源時就立即釋放它。

如何處理死鎖與超時

在程序中使用重試邏輯,可處理以下三種SQL錯誤代碼:

1、 904:返回這個代碼表示一條SQL語句是因為已達到資源限度而結(jié)束的。程序中可提交或回滾更改,并執(zhí)行重試邏輯。

2、 911:程序收到這個SQL代碼,表示因為沒有為鎖列表分配足夠的內(nèi)存,現(xiàn)在已達到數(shù)據(jù)庫的最大鎖數(shù)目。

3、 912:程序收到這個SQL代碼,表示死鎖或超時,依照904中的方法來解決。

以下是一段Java代碼,其捕捉返回的-911、-912、-904代碼,并進行重試:

 
 
 
  1. for (int i = 0; i < MAX_RETRY_ATTEMPTS; i++) {
  2. //以下代碼模擬一次事務
  3. try {
  4. stmt = conn.createStatement();
  5. System.out.println("Transaction started...");
  6. stmt.executeUpdate("UPDATE 1..."); //SQL語句1
  7. stmt.executeUpdate("UPDATE 2..."); // SQL語句2
  8. stmt.executeUpdate("UPDATE 3..."); // SQL語句3
  9. stmt.executeUpdate("UPDATE 3..."); // SQL語句4
  10. //提交所有更改
  11. conn.commit();
  12. System.out.println("事務已完成。");
  13. //確保只運行了一次。
  14. i = MAX_RETRY_ATTEMPTS;
  15. } catch (SQLException e) {
  16. /**
  17. *如果返回的SQL代碼為-911,回滾會自動完成,程序回滾至前一次的提交狀態(tài)。
  18. *程序?qū)⑦M行重試。
  19. */
  20. if (-911 == e.getErrorCode()) {
  21. //等待RETRY_WAIT_TIME
  22. try {
  23. Thread.sleep(RETRY_WAIT_TIME);
  24. } catch (InterruptedException e1) {
  25. //即使休眠被打斷,但仍要重試。
  26. System.out.println("休眠被打斷。");
  27. }
  28. }
  29. /**
  30. *如果返回的SQL代碼為-912,表示死鎖及超時。
  31. *如果是-904,代表已達到資源限度。
  32. *在這種情況下,程序?qū)⒒貪L并進行重試。
  33. */
  34. else if (-912 == e.getErrorCode() || -904 == e.getErrorCode()) {
  35. try {
  36. //需要回滾
  37. conn.rollback();
  38. } catch (SQLException e1) {
  39. System.out.println("無法回滾。"; color:black’> + e);
  40. }
  41. try {
  42. //等待RETRY_WAIT_TIME
  43. Thread.sleep(RETRY_WAIT_TIME);
  44. } catch (InterruptedException e1) {
  45. //即使休眠被打斷,但仍要重試。
  46. System.out.println("休眠被打斷。" + e1);
  47. }
  48. } else {
  49. //如果是其他錯誤,就不進行重試。
  50. i = MAX_RETRY_ATTEMPTS;
  51. System.out.println("有錯誤發(fā)生,錯誤代碼:"
  52. + e.getErrorCode() + " SQL狀態(tài):"
  53. +e.getSQLState() + "其他信息:" + e.getMessage());
  54. }

從上面也可看到,程序?qū)λ梨i、超時、最大鎖數(shù)目將會進行MAX_RETRY_ATTEMPTS次重試;其次,當“最大鎖數(shù)目”的情況發(fā)生時 (-911),程序不必手工進行回滾,因為此時的回滾是自動完成的;最后,無論何時返回-911、-904、-912代碼,程序應在下次重試前等待 RETRY_WAIT_TIME一段時間。


分享題目:Java程序中解決數(shù)據(jù)庫超時與死鎖
轉(zhuǎn)載來于:http://www.5511xx.com/article/djhpgjg.html