plsql例外_大例外背后的真相
plsql例外
異常可能是最被濫用的Java語言功能。 這就是為什么
讓我們打破一些神話。 沒有牙仙子。 圣誕老人不是真實的。 TODO評論。 finalfinalversion-final.pdf。 無皂肥皂。 而且…例外實際上是例外。 后者可能需要更多說服力,但是我們可以幫助您。
在這篇文章中,我們請經驗豐富的系統架構師和博客的長期朋友(最重要的是, 毛茸茸的帽子的忠實擁護者)Avishai Ish-Shalom加入我們,以快速討論Java應用程序中異常的當前狀態。 。 這是我們發現的。
根據定義,異常與正常情況相去甚遠
讓我們從Java官方文檔的引用開始:“異常是在程序執行期間發生的事件,破壞了正常的指令流程”。 誠實的披露:我們自己添加了上限。
實際上,在大多數應用程序中,正常的指令流充滿了這些所謂的“正常”異常的“正常”重復,這些異常會導致“正常”中斷。
在大多數應用程序中,噪聲水平越來越高,拋出,記錄,然后索引和分析的異常……大多數沒有意義。
除了對系統造成不必要的壓力外,這種操作噪音還會使您失去與真正重要的異常的聯系。 想象一下一個電子商務應用程序發生了一個新的重要異常,該異常開始發生時,表明出現了問題并受到影響,例如100個用戶無法檢出。 現在,用數千個無用的“正常”異常掩蓋它,并嘗試了解出了什么問題。
例如,大多數應用程序具有“正常”級別的錯誤事件。 在下面的屏幕截圖中,我們可以看到每小時大約有4k個事件:
Takipi的錯誤分析儀表板–錯誤趨勢
如果我們“幸運”,那么一個新的錯誤會在圖中顯示為尖峰,就像我們在這里一樣,在凌晨1點左右(一次)發生IllegalStateException,發生了數十萬次。 我們可以立即看到導致峰值的原因。
綠線表示事件總數,其余各行表示特定的異常和記錄的錯誤/警告。
危險來自異常,只有很少,很小但致命的實例被掩埋在所謂的“正常”異常級別內。
您所說的這些“正常”例外是什么?
與需要更改代碼才能解決的實際錯誤不同,如今的異常表明了很多其他情況,這些情況實際上并沒有任何可行的見解。 他們只會減輕系統壓力。 考慮任何有經驗的開發人員可以預期的以下兩種情況:
另一方面,真正的異常是您在編寫代碼時沒有意識到的事情,例如OutOfMemoryException甚至是NullPointerException,它們使事情意外地混亂了。 需要您采取措施解決問題的問題。
異常旨在崩潰和燃燒
未捕獲的異常會殺死您的線程,甚至在重要線程死機而其余線程仍在等待時,甚至可能使整個應用程序崩潰或使其處于某種“僵尸狀態”。 有些應用程序知道如何處理,大多數卻不知道。
Java中的異常的主要目的是幫助您捕獲錯誤并解決它,而不是跨入應用程序邏輯領域。 它們旨在幫助調試,這就是為什么他們嘗試從應用程序的角度包含盡可能多的信息。
這可能造成的另一個問題是狀態不一致,當應用程序流變得……跳動時,甚至比goto語句還要糟糕。 它具有相同的缺點,但也有一些曲折:
無例外地使用“錯誤”流程
如果您嘗試使用異常處理應由應用程序邏輯處理的可預測情況,那么您會遇到麻煩。 大多數Java應用程序都遇到同樣的麻煩。
本書預計不會發生的問題并不是真正的例外。 一個有趣的解決方案來自Scala的Futures –毫無例外地處理錯誤。 來自官方scala文檔的Scala示例:
import scala.util.{Success, Failure}val f: Future[List[String]] = Future {session.getRecentPosts }f onComplete {case Success(posts) => for (post <- posts) println(post)case Failure(t) => println("An error has occured: " + t.getMessage) }將來在內部運行的代碼可能會引發異常,但這些異常將被包含在內并且不會泄漏到外部。 Failure(t)分支明確表明了失敗的可能性,并且很容易遵循代碼執行。
在新的Java 8 CompletableFuture特性(我們最近才寫過)中,我們可以使用completeExceptionally(),盡管它不那么漂亮。
使用API??可以使圖變得更厚
假設我們有一個使用庫進行數據庫訪問的系統,那么數據庫庫如何將其錯誤暴露給外界? 歡迎來到狂野的西部。 并且請記住,該庫可能仍會引發一般錯誤,例如java.net.UnknownHostException或NullPointerException
現實生活中的一個例子就是一個包裝JDBC的庫,該庫包裝了JDBC,只是拋出了一個通用的DBException,而沒有讓您有機會知道出什么問題了。 也許這一切都很好,并且存在連接錯誤,或者……您實際上需要更改一些代碼。
常見的解決方案是使用基本異常(例如DBException)的數據庫庫,該庫異常將從中繼承。 這允許庫用戶使用一個try塊捕獲所有庫錯誤。 但是,可能導致庫錯誤的系統錯誤呢? 常見的解決方案是將發生的任何異常包裝起來。 因此,如果它無法解析DNS地址(更多是系統錯誤,然后是庫錯誤),它將捕獲該地址并拋出此更高級別的異常-庫用戶應該知道要捕獲該異常。 嘗試捕獲惡夢,帶有嵌套異常的提示包裝了其他異常。
如果我們將Actors混合在一起,則控制流程甚至變得更加混亂。 帶有異常的異步編程是一團糟。 它可以殺死一個Actor ,然后重新啟動它,一條消息將以原始錯誤發送給其他Actor ,您將丟失堆棧。
所以你能對它做點啥?
從頭開始并避免不必要的異常總是很容易,但是很可能并非如此。 使用現有的系統(例如使用5年的應用程序),您將需要進行大量的管道工作(如果幸運的話,并獲得管理部門的批準以解決噪音問題)。
理想情況下,我們希望所有異常都是可操作的,也就是說,驅動將阻止它們再次發生的操作,而不僅僅是承認有時會發生這些事情。
綜上所述,不可操作的異常會引起很多混亂:
- 性能
- 穩定性
- 監控/日志分析
- 而且...隱藏您要查看并采取行動的真實異常
解決方案是…進行艱苦的工作,以消除噪音并創建更有意義的控制流。 另一個創造性的解決方案是更改日志級別,如果這不是可行的例外,請不要將其記錄為錯誤。 那只是一個裝飾性的解決方案,但可能會讓您完成80%的工作。
歸根結底,日志和儀表板只是裝飾,需要解決該問題的核心并完全避免無法采取行動的異常。
在塔基皮(Takipi),我們最近發現平均記錄的錯誤中有97%來自前10個唯一錯誤 。 要查看應用程序中異常和已記錄錯誤的當前狀態,請連接Takipi代理,您將在幾分鐘內完全了解代碼在生產環境中的行為方式(以及如何修復)。 檢查一下 。
最后的想法
最重要的是,您是否有一個不會導致代碼更改的異常? 您甚至不應該浪費時間查看它。
這篇文章是基于Avishai所說的“可操作的異常”的閃電演講:
翻譯自: https://www.javacodegeeks.com/2016/06/truth-behind-big-exceptions-lie.html
plsql例外
總結
以上是生活随笔為你收集整理的plsql例外_大例外背后的真相的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: activiti脚本任务_Activit
- 下一篇: 安卓竖屏锁定哪里设置(安卓竖屏)