簡體   English   中英

Java中數據庫異常處理的更好方法

[英]Better way for DB exception handling in java

哪一種更好:針對這種情況的ErrorCode或Exception?

我見過這兩種錯誤處理技術。 我不知道每種技術的優缺點。

public void doOperation(Data data) throws MyException {
    try {
        // do DB operation
    } catch (SQLException e) {
        /* It can be ChildRecordFoundException, ParentRecordNotFoundException
         * NullValueFoundException, DuplicateException, etc..
         */
        throw translateException(e);
    }
}

要么

public void doOperation(Data data) throws MyException {
    try {
        // do DB operation
    } catch (SQLException e) {
        /* It can be "CHILD_RECORD_FOUND, "PARENT_RECORD_NOT_FOUND"
         * "NULL_VALUE_FOUND", "DUPLICATE_VALUE_FOUND", etc..
         */
        String errorCode = getErrorCode(e);
        MyException exc = new MyException();
        exc.setErrorCode(errorCode);
        throw exc;
    }
}

對於第二種方法,錯誤代碼檢索表單配置文件。 我們可以基於SQL Vender Code添加Error Code SQL Vender Code

SQL_ERROR_CODE.properties

#MySQL Database
1062=DUPLICATE_KEY_FOUND
1216=CHILD_RECORD_FOUND
1217=PARENT_RECORD_NOT_FOUND
1048=NULL_VALUE_FOUND
1205=RECORD_HAS_BEEN_LOCKED

方法1的呼叫者客戶端

    try {

    } catch(MyException e) {
        if(e instanceof ChildRecordFoundException) {
            showMessage(...);
        } else if(e instanceof ParentRecordNotFoundException) {
            showMessage(...);
        } else if(e instanceof NullValueFoundException) {
            showMessage(...);
        } else if(e instanceof DuplicateException) {
            showMessage(...);
        }
    }

方法2的呼叫者客戶端

    try {

    } catch(MyException e) {
        if(e.getErrorCode().equals("CHILD_RECORD_FOUND")) {
            showMessage(...);
        } else if(e.getErrorCode().equals("PARENT_RECORD_NOT_FOUND") {
            showMessage(...);
        } else if(e.getErrorCode().equals("NULL_VALUE_FOUND") {
            showMessage(...);
        } else if(e.getErrorCode().equals("DUPLICATE_VALUE_FOUND") {
            showMessage(...);
        }
    }

我建議使用Spring的JDBCTemplate 它將大多數現有數據庫的異常轉換為特定的未經檢查的異常,例如DataIntegrityViolationException 它還將在消息中包含原始SQL錯誤。

奇怪的問題,因為這兩種方法都做同樣的事情:它們將已檢查的SqlException轉換為另一個似乎未被檢查的異常。 因此,第一個是更好的方法,因為它將其轉移到一個方法中。

兩者都留下一些問題要問:

  • 沒有一些可以進行此轉換的基礎結構(另一個答案中提到了Spring模板)

  • 您是否真的要檢查異常,在我看來,它們幾乎不值得麻煩。

  • 誰在真正地處理異常,異常是否獲得了所需的所有信息? 通常,我希望有關MyException內部失敗的事務的一些其他信息,例如:我們試圖做什么? (例如更新業務對象); 在什么樣的物體上? (例如一個人); 我們/用戶如何識別對象(例如person.id + person.lastname + person.firstname)。 如果您想產生日志/錯誤消息,而不是告訴您或您的用戶“糟糕,出問題了”,則需要此類信息。

  • 為什么MyException是可變的(至少在第二個示例中)

比任何一個更好的設計都是通過擴展RuntimeException使您的自定義異常不受檢查。

我希望您的異常包裝第一個異常,因此以這種方式進行編碼也將更好:

MyException exception = new MyException(e); // wrap it.

如果這樣做,則首選第二個。 更多信息更好。

恕我直言,這取決於您的代碼與SQL緊密耦合的程度。

如果該方法始終與SQL結合使用(* 1),我只需要聲明並重新拋出SQLException (在清理/關閉資源之后)。 然后,可以識別SQL的高級方法將在其認為合適的情況下對其進行處理(也許他們需要所有詳細信息,也許不需要)。

如果將來某個時候可以將方法更改為另一個不使用SQL的方法,那么我將選擇第二種方法。

(1):對於這種假設要格外悲觀:“我認為我們不會改變”應該解釋為“可能我們會想要改變”。 “我們不會改變”是指“無論如何都不會破壞很多其他方法,我們就無法改變”。

一種差異將是您catch異常的方式。 在第一種情況下,您可以catch異常,並且知道錯誤是什么。 在第二種情況下,您必須catch異常並檢查代碼以查看錯誤是什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM