Java重試代碼設計 java實現(xiàn)重試

北大青鳥java培訓:在Java程序中處理數(shù)據庫超時與死鎖?

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

10年積累的網站設計、成都網站設計經驗,可以快速應對客戶對網站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網絡服務。我雖然不認識你,你也不認識我。但先網站制作后付款的網站建設流程,更有玉田免費網站建設讓你可以放心的選擇與我們合作。

什么是數(shù)據庫鎖定與死鎖鎖定(Locking)發(fā)生在當一個事務獲得對某一資源的“鎖”時,這時,其他的事務就不能更改這個資源了,這種機制的存在是為了保證數(shù)據一致性;在設計與數(shù)據庫交互的程序時,必須處理鎖與資源不可用的情況。

鎖定是個比較復雜的概念,仔細說起來可能又需要一大篇,所以在本文中,只把鎖定看作是一個臨時事件,這意味著如果一個資源被鎖定,它總會在以后某個時間被釋放。

而死鎖發(fā)生在當多個進程訪問同一數(shù)據庫時,其中每個進程擁有的鎖都是其他進程所需的,由此造成每個進程都無法繼續(xù)下去。

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

隔離級別問題現(xiàn)象丟失修改讀“臟”數(shù)據不可重復讀“虛”可重復讀取NoNoNoNo讀取穩(wěn)定性NoNoNoYes光標穩(wěn)定性NoNoYesYes未提交的讀NoYesYesYes表1:DB2的隔離級別與其對應的問題現(xiàn)象在只讀模式中,就可以防止鎖定發(fā)生,而不用那些未提交只讀隔離級別的含糊語句。

山西電腦培訓發(fā)現(xiàn)一條SQL語句當使用了下列命令之一時,就應該考慮只讀模式了

java問題,項目運行時,for循環(huán)會有3中狀態(tài)1.成功 2.失敗 3.可重試

你好 首先這段代碼運行的結果是1 2 4 3 2 4 3 2 8。從運行結果可以看出這段程序執(zhí)行for循環(huán)執(zhí)行了兩次(因為輸出兩次4)。

要理解for循環(huán)的本質:首先執(zhí)行test(‘1’)方法輸出1,

再判斷test('2')(x=2)為真所以輸出2,4,這時第一次進入循環(huán)。注意這時x的值是2.結束第一次循環(huán)后,執(zhí)行test(‘3’),所以輸出3。

這時又要判斷test('2')(x=2)是否為真,因為為真所以執(zhí)行循環(huán),所以輸出:2,4,這時又要去執(zhí)行test(‘3’),所以輸出3。執(zhí)行之后再判斷test('2')(x=2)是否為真,因為此時x的值為3,不滿足判斷條件(但是test(‘2’)執(zhí)行了)所以輸出2,退出循環(huán)輸出count的值為8(因為之前調用test(char num)方法8次),所以輸出8。因此最終結果為1 2 4 3 2 4 3 2 8。其實這個for循環(huán)語句和for(int i=0;i2;i++)本質一樣,好好想想這個for循環(huán)的執(zhí)行過程就明白了。

希望我的回答對你有幫助,謝謝~

JAVA程序設計,多線程且避免死鎖

JAVA中幾種常見死鎖及對策:解決死鎖沒有簡單的方法,這是因為線程產生死鎖都各有各的原因,而且往往具有很高的負載。大多數(shù)軟件測試產生不了足夠多的負載,所以不可能暴露所有的線程錯誤。在這里中,下面將討論開發(fā)過程常見的4類典型的死鎖和解決對策。(1)數(shù)據庫死鎖在數(shù)據庫中,如果一個連接占用了另一個連接所需的數(shù)據庫鎖,則它可以阻塞另一個連接。如果兩個或兩個以上的連接相互阻塞,則它們都不能繼續(xù)執(zhí)行,這種情況稱為數(shù)據庫死鎖。數(shù)據庫死鎖問題不易處理,通常數(shù)據行進行更新時,需要鎖定該數(shù)據行,執(zhí)行更新,然后在提交或回滾封閉事務時釋放鎖。由于數(shù)據庫平臺、配置的隔離級以及查詢提示的不同,獲取的鎖可能是細粒度或粗粒度的,它會阻塞(或不阻塞)其他對同一數(shù)據行、表或數(shù)據庫的查詢。基于數(shù)據庫模式,讀寫操作會要求遍歷或更新多個索引、驗證約束、執(zhí)行觸發(fā)器等。每個要求都會引入鎖。此外,其他應用程序還可能正在訪問同一數(shù)據庫模式中的某些對象,并獲取不同應用程序所具有的鎖。所有這些因素綜合在一起,數(shù)據庫死鎖幾乎不可能被消除了。值得慶幸的是,數(shù)據庫死鎖通常是可恢復的:當數(shù)據庫發(fā)現(xiàn)死鎖時,它會強制銷毀一個連接(通常是使用最少的連接),并回滾其事務。這將釋放所有與已經結束的事務相關聯(lián)的鎖,至少允許其他連接中有一個可以獲取它們正在被阻塞的鎖。由于數(shù)據庫具有這種典型的死鎖處理行為,所以當出現(xiàn)數(shù)據庫死鎖問題時,數(shù)據庫常常只能重試整個事務。當數(shù)據庫連接被銷毀時,會拋出可被應用程序捕獲的異常,并標識為數(shù)據庫死鎖。如果允許死鎖異常傳播到初始化該事務的代碼層之外,則該代碼層可以啟動一個新事務并重做先前所有工作。當出現(xiàn)問題就重試,由于數(shù)據庫可以自由地獲取鎖,所以幾乎不可能保證兩個或兩個以上的線程不發(fā)生數(shù)據庫死鎖。此方法至少能保證在出現(xiàn)某些數(shù)據庫死鎖情況時,應用程序能正常運行。(2)資源池耗盡死鎖客戶端的增加導致資源池耗盡死鎖是由于負載而造成的,即資源池太小,而每個線程需要的資源超過了池中的可用資源。假設連接池最多有10個連接,同時有10個對外部并發(fā)調用。這些線程中每一個都需要一個數(shù)據庫連接用來清空池?,F(xiàn)在,每個線程都執(zhí)行嵌套的調用。則所有線程都不能繼續(xù),但又都不放棄自己的第一個數(shù)據庫連接。這樣,10個線程都將被死鎖。研究此類死鎖,會發(fā)現(xiàn)線程存儲中有大量等待獲取資源的線程,以及同等數(shù)量的空閑且未阻塞的活動數(shù)據庫連接。當應用程序死鎖時,如果可以在運行時檢測連接池,就能確認連接池實際上已空。修復此類死鎖的方法包括:增加連接池的大小或者重構代碼,以便單個線程不需要同時使用很多數(shù)據庫連接?;蛘呖梢栽O置內部調用使用不同的連接池,即使外部調用的連接池為空,內部調用也能使用自己的連接池繼續(xù)。(3)單線程、多沖突數(shù)據庫連接死鎖對同一線程執(zhí)行嵌套的調用有時出現(xiàn)死鎖,此情形即使在非高負載系統(tǒng)中通常也會發(fā)生。當?shù)谝粋€(外部)連接已獲取第二個(內部)連接所需要的數(shù)據庫鎖,則第二個連接將永久阻塞第一個連接,并等待第一個連接被提交或回滾,這就出現(xiàn)了死鎖情形。因為數(shù)據庫沒有注意到兩個連接之間的關系,所以數(shù)據庫不會將此情形檢測為死鎖。這樣即使不存在并發(fā),此代碼也將導致死鎖。此情形有多種具體的變種,可以涉及多個線程和兩個以上的數(shù)據庫連接。(4)Java虛擬機鎖與數(shù)據庫鎖沖突這種情形發(fā)生在數(shù)據庫鎖與Java虛擬機鎖并存的時候。在這種情況下,一個線程占有一個數(shù)據庫鎖并嘗試獲取Java虛擬機鎖。同時,另一個線程占有Java虛擬機鎖并嘗試獲取數(shù)據庫鎖。此時,數(shù)據庫發(fā)現(xiàn)一個連接阻塞了另一個連接,但由于無法阻止連接繼續(xù),所以不會檢測到死鎖。Java虛擬機發(fā)現(xiàn)同步的鎖中有一個線程,并有另一個嘗試進入的線程,所以即使Java虛擬機能檢測到死鎖并對它們進行處理,它還是不會檢測到這種情況。 總而言之,JAVA應用程序中的死鎖是一個大問題——它能導致整個應用程序慢慢終止,還很難被分離和修復,尤其是當開發(fā)人員不熟悉如何分析死鎖環(huán)境的時候。五.死鎖的經驗法則筆者在開發(fā)中總結以下死鎖問題的經驗。(1)對大多數(shù)的Java程序員來說最簡單的防止死鎖的方法是對競爭的資源引入序號,如果一個線程需要幾個資源,那么它必須先得到小序號的資源,再申請大序號的資源??梢栽贘ava代碼中增加同步關鍵字的使用,這樣可以減少死鎖,但這樣做也會影響性能。如果負載過重,數(shù)據庫內部也有可能發(fā)生死鎖。(2)了解數(shù)據庫鎖的發(fā)生行為。假定任何數(shù)據庫訪問都有可能陷入數(shù)據庫死鎖狀況,但是都能正確進行重試。例如了解如何從應用服務器獲取完整的線程轉儲以及從數(shù)據庫獲取數(shù)據庫連接列表(包括互相阻塞的連接),知道每個數(shù)據庫連接與哪個Java線程相關聯(lián)。了解Java線程和數(shù)據庫連接之間映射的最簡單方法是向連接池訪問模式添加日志記錄功能。(3)當進行嵌套的調用時,了解哪些調用使用了與其它調用同樣的數(shù)據庫連接。即使嵌套調用運行在同一個全局事務中,它仍將使用不同的數(shù)據庫連接,而不會導致嵌套死鎖。(4)確保在峰值并發(fā)時有足夠大的資源池。(5)避免執(zhí)行數(shù)據庫調用或在占有Java虛擬機鎖時,執(zhí)行其他與Java虛擬機無關的操作。 最重要的是,多線程設計雖然是困難的,但在開始編程之前詳細設計系統(tǒng)能夠幫助你避免難以發(fā)現(xiàn)死鎖的問題。死鎖在語言層面上不能解決,就需要一個良好設計來避免死鎖。

Spring Boot 一個注解搞定重試機制,不能太優(yōu)雅了

在實際工作中,重處理是一個非常常見的場景,比如:

這些錯誤可能是因為網絡波動造成的,等待過后重處理就能成功。通常來說,會用 try/catch , while 循環(huán)之類的語法來進行重處理,但是這樣的做法缺乏統(tǒng)一性,并且不是很方便,要多寫很多代碼。

然而 spring-retry 卻可以通過注解,在不入侵原有業(yè)務邏輯代碼的方式下,優(yōu)雅的實現(xiàn)重處理功能。

spring系列的 spring-retry 是另一個實用程序模塊,可以幫助我們以標準方式處理任何特定操作的重試。在 spring-retry 中,所有配置都是基于簡單注釋的。

Spring Boot 基礎就不介紹了,推薦下這個實戰(zhàn)教程:

來簡單解釋一下注解中幾個參數(shù)的含義:

當重試耗盡時還是失敗,會出現(xiàn)什么情況呢?

當重試耗盡時, RetryOperations 可以將控制傳遞給另一個回調,即 RecoveryCallback 。 Spring-Retry 還提供了 @Recover 注解,用于@Retryable重試失敗后處理方法。如果不需要回調方法,可以直接不寫回調方法,那么實現(xiàn)的效果是,重試次數(shù)完了后,如果還是沒成功沒符合業(yè)務判斷,就拋出異常。

可以看到傳參里面寫的是 Exception e ,這個是作為回調的接頭暗號(重試次數(shù)用完了,還是失敗,我們拋出這個 Exception e 通知觸發(fā)這個回調方法)。

對于 @Recover 注解的方法,需要特別注意的是:

本篇主要簡單介紹了Springboot中的 Retryable 的使用,主要的適用場景和注意事項,當需要重試的時候還是很有用的。

當前文章:Java重試代碼設計 java實現(xiàn)重試
分享地址:http://www.muchs.cn/article8/hphhop.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、微信公眾號、App設計、搜索引擎優(yōu)化、ChatGPT

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網站建設