【问题标题】:Spring Retry doesn't work with a try-catch blockSpring Retry 不适用于 try-catch 块
【发布时间】:2021-10-19 12:37:54
【问题描述】:

我有一个方法,我想在 SQLRecoverableException 发生时重试。我用@Retryable(value={SQLRecoverableException.class}) 注释了该方法并在我的应用程序中启用了重试。但是,此特定方法包含一个用于处理 RuntimeException 的 try-catch 块。重试现在不起作用,因为在 try-catch 块中捕获了任何异常。我希望该方法在错误处理之前重试 3 次。这是否可以通过开箱即用的 Spring Retry 实现,还是我必须寻求更自定义的解决方案?

【问题讨论】:

  • 据我所知,SQLRecoverableException 不是RuntimeException,因此不应被catch-block 捕获(如果catch-block 仅捕获RuntimeException s)。请edit发帖并添加相关代码。
  • 请贴出代码。如果您在方法本身中捕获异常,那么 Spring 当然无法对其采取行动。如果您在另一个调用相关方法的方法中捕获它,它应该可以工作。

标签: java spring-jdbc spring-retry


【解决方案1】:

不仅可以通过注释处理重试,因此也许这会有所帮助:

try {
    withRetry().execute(context -> {
        myMethodThatCatchException();
        return null;
    });
} catch (RuntimeException re) {
    // ..
}

private RetryTemplate withRetry() {
    RetryTemplate retryTemplate = new RetryTemplate();
    BackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    retryTemplate.setBackOffPolicy(backOffPolicy);
    SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, Collections.singletonMap(SQLRecoverableException.class, true));
    retryTemplate.setRetryPolicy(retryPolicy);
    return retryTemplate;
}

【讨论】:

    【解决方案2】:

    您可以在 try-catch 块中捕获和重新抛出特定异常

    @Retryable(value={SQLRecoverableException.class})
    void someMethod() {
       try {
          ...
       } catch (SQLRecoverableException retryable) { 
           // don't handle here, let it be handled by @Retryable-mechanism
           throw retryable;
       } catch (RuntimeException other) {
           // handle other non-retryable exceptions
       }
    }
    

    【讨论】:

      【解决方案3】:
      @Retryable(value={SQLRecoverableException.class},maxAttempts=3)
      public boolean methodA(){
      try{.....}
      catch(RuntimeException ex){ // apart from given above one
      \\handle catch exception
      } 
      }
      
      @Recover
      public boolean recoverMethodA(SQLRecoverableException a){
       logger.info(a.getMessage());
      return false;
      }
      

      经过一些观察,我发现 -

      • Retryable 不适用于您传入可重试值的已处理异常。
      • 如果您使用同一类中的另一个方法调用可重试方法,则可重试方法将不起作用。 ex - boolean methodA() --> boolean retryableMethodB() 如果您应该在方法A上应用可重试。(如果使用控制器)

      【讨论】:

        猜你喜欢
        • 2012-04-29
        • 2012-05-14
        • 2023-01-16
        • 2017-09-22
        • 1970-01-01
        • 1970-01-01
        • 2011-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多