【问题标题】:Spring JPA - Handle DB/Repo exceptionsSpring JPA - 处理 DB/Repo 异常
【发布时间】:2020-08-03 05:21:33
【问题描述】:

我有一个 SpringBoot 应用程序,它使用 spring 数据 CrudRepository 来持久化消息。 当出现数据库服务器端异常时,应用程序不要丢失消息,这一点很重要。

例如数据库服务器无法访问或数据库实例面临内存问题等。

因此我想特别处理它们并重试直到数据库服务器端问题 解决。 我遇到了这篇文章,它解释了 Spring JPA 抛出的 Exceptionhttps://danielkvist.net/code/spring-data-crudrepository-exceptions 它总结了 Spring JPA 的 Exception 层次结构。因此我应用了Exception 处理逻辑。

saveMessages (List<Message> messages)
{
    try {
        crudRepo.saveAll(messages);
    } catch (NonTransientDataAccessException | TransientDataAccessException e) {
      // throw custom retryable exception for the service to retry
      throw new CustomRetryableException(e);
    }
}

当代码在生产中执行时,上面的逻辑失败了,因为抛出了不同类型的异常。 例如当 DB 服务器关闭时 CannotCreateTransactionException 被抛出,或者当 DB 服务器在请求 TransactionSystemException 之间重新启动时被抛出。 所以我想我错过了处理TransactionException 的子类

问题:

  1. 处理TransactionException 的子类的最佳方法是什么? (在我开头提到的上下文中)

  2. 是否还有其他我应该处理的异常(DataAccessExceptionTransactionException 除外?

【问题讨论】:

    标签: java spring spring-boot exception spring-data-jpa


    【解决方案1】:

    您可以捕获异常的父类,但如果您想捕获/处理 DAO/服务中的异常,我只会捕获 RuntimeException

    try {
        crudRepo.saveAll(messages);
    } catch (RuntimeException e) {
      // add log here!
    
      throw new CustomRetryableException(e);
    }
    

    另一种方法是使用通用的ExceptionHandler在单独的类中定义这个逻辑(你也可以为不同的异常定义不同的处理程序)

     @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> genericHandler(HttpServletRequest request, RuntimeException ex) {
    

    更多信息和示例here

    【讨论】:

    • 感谢您帮助我。但我不应该处理每个运行时异常。例如ScriptExecutionException 可能由于 SQL 格式错误而发生。现在没有重试的意义,因为它是客户端问题,因为数据库在这里不能做太多事情。我特别想捕获数据库端异常。我认为通过处理 NonTransientDataAccessException |、TransientDataAccessException 和 TransactionException 我应该很好。但想确认一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    相关资源
    最近更新 更多