<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我愛oo,我愛java

    交流blog QQ:421057986 oofrank@donews

    Spring 中的異常悖論

    這個題目可能有些危言悚聽,使用Spring的同行不用害怕,只是因為工作中碰到一些問題,才偶然想到這個問題。

    首先要明確兩個問題:
    1、系統隔離原則:
        即系統間依賴應該是清晰的,不因為一個系統的故障影響其他系統,甚至整個系統。
    2、簡單應用習慣:
        普通程序員只會處理checked Exception,負責任的程序員會處理被調用的函數可能拋出的異常(根據源碼或javadoc)
     

    我們碰到一個情況:
    使用Spring的 init 特性初試化一個bean--一個使用Qutarz的調度程序。初試化過程中會拋出RuntimeException,從而造成Spring容器的整個初試化失敗。首先我們修改了程序,捕獲了所有異常,隨后在編碼指南中加入了一句話:"所有使用Spring-init機制初試化的類必須在init中捕獲所有異常:Exception"。因為只有如此才能保證整個系統不會因為局部問題而完全癱瘓。

    我覺得這是Spring對異常處理的一個悖論:
    正方:底層異常都封裝成Runtime的,經過幾次包裝--->簡單應用習慣--->異常被拋出領域層(init場景下:由Spring處理)
    反方: 一個類的失敗可以造成整個系統的失敗---->Spring被RuntimeException宕掉---->不符合系統隔離原則


    當然充分的測試可能可以解決這個問題:但是要注意,測試只能證明系統有bug,不能證明系統沒有bug。

    解決方案:
    1、好的設計習慣:將應該隔離的系統隔離開-->使用不同的Spring配置文件.
    2、接口層錯誤處理:在接口層應該盡量對可以處理的異常進行處理,然后以合理的方式傳遞給上層.


    PS:在與人交互的系統中都應該給最終用戶合理的錯誤提示,所以表現層應該盡量捕獲非業務的RuntimeException給最終用戶更好的操作感受。

    posted on 2006-01-19 21:45 兼聽則明 閱讀(1453) 評論(19)  編輯  收藏 所屬分類: java

    評論

    # re: Spring 中的異常悖論 2006-01-20 08:54 darkbluefeeling

    我覺得初始化如果都出問題了,系統就應該halt了,把問題隱藏起來可比暴露出來問題多的多。畢竟是初始化,這兒不應該出問題的。  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 08:59 王麻子

    不是表現層應該盡量捕獲非業務的RuntimeException給最終用戶更好的操作感受,,
    而是業務邏輯層根據業務需求拋出一系列的應用異常.
    如果表現層遇到了非應用異常的其它情況,就是編程錯誤,或系統錯誤.  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 10:05 qiu

    測試只能證明系統有bug,不能證明系統沒有bug。


    不是應該感謝spring幫你找到了一個bug么?

      回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 10:25 兼聽則明

    to: darkbluefeeling
    當然,如果重要的系統部分不能init成功,系統應該首先排錯;但如果只是很小的一個部分不能init成功--就造成系統不能啟動,我認為是系統設計有問題。
    比如:如果聲卡驅動裝載不成功,操作系統就不能啟動,只是 "蘭屏",你將大罵操作系統,而如果硬盤有故障,操作系統不能引導,則是罵不到操作系統。  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 10:34 兼聽則明

    to: 王麻子
    我覺得你說的是對的,但是有時候需求并沒有分析完全,在系統上線后才發生這個問題,即本該是“業務需求拋出一系列的應用異常.”但實際拋出了RuntimeException,我認為同樣不該展現給客戶“異樣”的異常:
    例:----僅僅是例子!
    我使用Qutarz作調度,當一個調度不能被fire時,它將拋出RuntimeException,我們的測試(案例)沒有發現這個情況,到系統上線時,拋出異常,如果隨便給客戶一個"系統錯誤",我認為是很不好的,因為客戶會認為發生了很嚴重的錯誤,實際只是簡單的輸入錯誤而已,即按年調度,但在開始時間到結束時間端內沒有該調度觸發的時機。
      回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 10:39 兼聽則明

    to qiu:
    然,Spring幫我捉了一只蟲,
    你是否感謝MS幫你捉了 其他軟件的蟲呢 --------寫了半天帖子---系統崩潰,沒能保存----
    在沒有上線時,觸發bug非常好!可是如果系統正式運行時發生的癱瘓級異常,作為軟件開發者還會笑的出來嗎?
    ---顯然,使用某種通知機制通知管理員,由管理員來需求開發人員支持,好過使用系統宕掉的方式通知軟件開發者....  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 10:40 yuxie

    Road從來沒有說過底層異常都封裝成Runtime的,他的意思是不能被恢復的異常你要做成Runtime的(one-on-one那本書),像這個task的初始化,你捕捉了有什么用呢?異常還是已經發生了,而且沒有被恢復!  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 11:20 兼聽則明

    to: yuxie

    實際我都捕獲了,并忽略了----忽略也是一種“你說的恢復”,另外“不能被恢復的異常你要做成Runtime的”的問題在于現在Spring中把所有的異常都封裝成Runtime的了----當然,我們還可以通過捕獲處理我們想處理的問題。  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 11:20 pesome

    不能恢復就一定要做成runtime exception?without ejb還說checked exception可以替代返回值呢。要具體問題具體分析,不能太教條。  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 11:23 兼聽則明

    在充分設計和充分測試的情況下,這個問題可以被控制到很小的范圍,但是誰能保證設計和測試足夠"充分"呢?  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 11:44 兼聽則明

    checked exception可以替代返回值::確實如此,實際上業務異常是以返回值的身份出現的,更不該是"異常",比如login()方法可能拋出 UnknownUserException,WrongPasswordException....
    而 addUser() 可以拋出UserExistException 比 主鍵沖突的 DataAccessException好的多.  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 12:50 yuxie

    關于返回值得問題,我認為拋出Checked Exception作為返回值是業務層的事情,而我們說的底層的應用,是需要跟業務層松耦合的。如果底層(集成層等)拋出一個checked exception,你的業務邏輯層就必須要捕獲它或者throw掉,這就增加了系統的耦合性。所以spring把大部分異常封裝成runtime是有道理的。如果他不做成runtime的,你的業務層就必須import org.springframework.…….XXException,緊綁定在spring上,豈不是很郁悶!  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 13:42 兼聽則明

    to yuxie:
    你說的很對,Spring最好不要侵入我們的領域。

    但對于 “addUser() 可以拋出UserExistException 比 主鍵沖突的 DataAccessException好的多” 問題,我們怎樣才能處理到底是數據庫連接異常,還是僅僅是重復UserID的輸入錯誤(即主鍵沖突--業務主鍵)呢?  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 13:50 pesome

    spring設計成runtime是合理的,而我們catch它的異常也是合理的  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 15:26 yuxie

    to 兼聽則明:
    很簡單亞,你只要做一個checkUserExist()的方法就是了,如果返回true就throw exception。通過catch DataAccessException來判斷是否用重復記錄,我覺得不是一個好的方法。
    數據庫一旦發生異常,拋出DataAccessException,就應該是一個非常嚴重的錯誤,此時系統已無法正常使用,直接在表現層總的catch一下,給用戶一個錯誤界面就ok了。
    如果在checkUserExist()之后,兩個用戶同時插了相同的數據,這確實是個問題~歐沒有想到好的方法  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 15:33 兼聽則明

    to yuxie:
    如果數據庫記錄很多,checkUserExist(),成本很高,另外,如果有并發沖突時checkUserExist()將很可能失效。--如你所說!  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 15:47 pesome

    拋出DataAccessException也不一定是非常嚴重的問題,更不表示系統已無法正常使用。說到底,先check還是拋錯都是由成本決定,由出錯的幾率決定。  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-20 17:24 兼聽則明

    to pesome:
    同意  回復  更多評論   

    # re: Spring 中的異常悖論 2006-01-21 17:14 yuxie

    dao層try一下,如果是有重復記錄,就拋出checked exception(dao層公用的),業務層捕獲即可。  回復  更多評論   

    主站蜘蛛池模板: 91亚洲国产成人精品下载| 国产福利免费视频| 亚洲成AV人片在线播放无码| 最近最好的中文字幕2019免费 | 免费特级黄毛片在线成人观看| 你是我的城池营垒免费看| 亚洲а∨精品天堂在线| 久久亚洲精品无码VA大香大香| 免费在线观看中文字幕| 四虎国产精品免费久久| 人妻无码一区二区三区免费| 午夜成人无码福利免费视频| 亚洲国产综合精品中文第一| 亚洲视频一区二区在线观看| 亚洲区小说区图片区QVOD| 亚洲精品无码久久不卡| 四虎永久免费影院在线| 成人毛片视频免费网站观看| 免费观看激色视频网站(性色)| 免费久久人人爽人人爽av| xxxx日本在线播放免费不卡| 美女被免费视频网站| 亚洲精品国产av成拍色拍| 亚洲va乱码一区二区三区| 亚洲精品资源在线| 久久精品蜜芽亚洲国产AV| 亚洲av永久无码精品漫画| 亚洲色欲色欲www在线丝| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 国产亚洲美女精品久久久久| 亚洲最大中文字幕无码网站| 亚洲日产2021三区| 亚洲国产模特在线播放| 亚洲国产午夜电影在线入口| 亚洲人成在线精品| 亚洲大成色www永久网址| 亚洲天堂2017无码中文| 亚洲AV无码专区在线亚| 亚洲卡一卡二卡乱码新区| 亚洲一区二区三区丝袜| 在线亚洲高清揄拍自拍一品区|