簡體   English   中英

如何捕獲spring boot data jpa的連接被拒絕異常

[英]how to catch connection refused exception of spring boot data jpa

我正在使用 Spring Boot 創建微服務應用程序。 所以,想想有 2 個服務叫 A 和 B。A 請求通過 HTTP 對 B 執行一些操作。 因此,當請求到來時,數據庫可能在某些時候不可用。 在這種情況下,A服務必須知道它是來自數據庫端的連接錯誤還是來自服務B的其他異常之一。如果A服務器知道這一點,A服務器可以在連接修復后再次replay請求。 為此,我想從 MYSQL 拋出的異常中過濾connection-exception 但我試圖通過使用Exception在服務層中捕獲它。 不幸的是,錯誤沒有被捕獲。 如下代碼。

try {
   userRepository.incrementReputationByOne(userUid);
} catch (Exception e) {
   //the exception doesn't come here
   e.printStackTrace();
}

我想將 Http 狀態代碼設置為HttpStatus.SERVICE_UNAVAILABLE 然后服務 A 知道錯誤是由於數據庫或端點的連接問題造成的。 服務器可以在一段時間或某個預定時間后再次重試請求。

你無法像這樣在服務層捕獲與存儲庫相關的 SQLException。 因為事務是從服務層管理的。 因此,您必須在控制器層中使用 try-catch 塊。 否則,請求狀態將為internal-server-error 如果您在控制器層捕獲事務錯誤,則必須為每個重復相同的捕獲過程。 因此您可以使用ControllerAdvice 反正spring不會直接拋出SQL異常。 而不是那個春天會拋出CannotCreateTransactionException 它包含ConnectException spring 提供了一種方便的方法來確定它是否包含您正在尋找的異常。


沒有 ControllerAdvice

在控制器的方法中,您可以捕獲如下錯誤。

    @PutMapping
    public ResponseEntity<?> incrementByOne(@RequestParam("user_uid") String userUid) {
        try {
            userService.incrementReputationByOne(userUid);
        } catch (CannotCreateTransactionException e) {
            if (e.contains(ConnectException.class)) {
                log.debug("ConnectException {}", e.getMessage());
                return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();
            } else {
                ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
            }
        }
        return ResponseEntity.ok().build();
    }

使用 ControllerAdvice

如果您使用 ControllerAdvice 來捕獲異常,這很容易,並且您不想將數據庫異常也包含在服務層或控制器層。

@ControllerAdvice
@Slf4j
@ResponseBody
public class DatabaseExceptionHandler {
    @ExceptionHandler(value = {CannotCreateTransactionException.class})
    public ResponseEntity<?> cannotCreateTransactionException(CannotCreateTransactionException exception, WebRequest request) {
        if (exception.contains(ConnectException.class)) {
            log.error("DB ConnectException :  {}", exception.getMessage());
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();
        }else {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}

在您的服務層中保留您的代碼而不會發現錯誤。 ControllerAdvice將處理異常。

暫無
暫無

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

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