当前位置: 首页 > 知识库问答 >
问题:

Spring重试模板不能使用@org.springframework.transaction.annotation.transactional

堵才哲
2023-03-14
@Configuration
public class RetryTemplateConfig {

    @Bean
    public  RetryTemplate createRetryTemplate(){
        RetryTemplate retryTemplate = new RetryTemplate();

        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(5000l);
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);

        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(5);
        retryTemplate.setRetryPolicy(retryPolicy);

        return retryTemplate;
    }

}


@Service
public class MessageService {

    @Autowired
    private RetryTemplate retryTemplate;

    @Autowired
    MessageRepo messageRepo;

    @Transactional
    public void sendMessage(Message message) throws RuntimeException{

        retryTemplate.execute(retryContext -> {
            log.info("Executing for {}  " ,  retryContext.getRetryCount());
            Message model = new Message();
            messageRepo.save(model);
            return "";
        });
    }
}
@Service
@EnableRetry
public class MessageService {

    @Autowired
    private RetryTemplate retryTemplate;

    @Autowired
    MessageRepo messageRepo;

    @Retryable(
            value = {RuntimeException.class},
            backoff = @Backoff(delay = 2000),
            maxAttempts = 5
    )
    @Transactional
    public void sendMessage(Message message) throws RuntimeException{
        Message model = new Message();
        messageRepo.save(model);
    }
}


    @Recover
    public void recover(){
        log.info("Recover is called ");
    }
}

有人能解释这两种不同行为的原因并建议我重新尝试的最佳方法吗?(我使用的是JPA数据

共有1个答案

夏志国
2023-03-14

在第一种情况下,当使用retryTemplate时,甚至在执行到达retryTemplate.execute(...)调用之前就会发生异常,因为spring无法打开所需的事务(通过@transactional注释,因为打开事务需要一个DB连接),

所以异常发生在spring framework级别,而不是在您的方法中,因此您的重试模板在这种情况下是无用的。

在第二种情况下,打开事务发生在重试范围内,因此重试捕获异常,一切正常。

 类似资料:
  • 我试图测试使用自定义重试策略的重试模板。为了做到这一点,我使用以下示例: https://github.com/spring-projects/spring-retry/blob/master/src/test/java/org/springframework/retry/support/retrytemplatetests.java#l57 基本上,我的目标是在得到一些特定的http错误状态(例

  • 请注意 这个重试功能在Spring Batch 2.2.0里面退出,现在它是Spring Retry的一部分. 为了让这个进程更稳定,更小的失败性。有时它帮助自动重试一个失败的操作以防止它可能在后续的尝试成功。本质上,这种处理会导致误差。例如,远程调用网络服务或RMI服务失败是由于在短暂的数据更新后,网络故障或冻结异常aDeadLockLoserException.例如重试这种自动化操作,Spri

  • 我使用SpringKafka的KafkaTemplate以异步方式发送消息,并使用回调进行正确的错误处理。 此外,我已将 Kafka 生产者配置为具有最大重试次数 (MAX_INTEGER)。 然而,可能有一些与avro序列化相关的错误,但对于那些重试没有帮助。那么,我如何在不重试的情况下逃避这些错误,但对于其他与代理相关的问题,我想重试?

  • 使用,我在基本模板中定义了一个,其中包含默认内容。在某些情况下,我希望这个块为空,所以我想我可以重新定义它的名称,并使它不包含以下内容: 不知何故,Go似乎认为这个定义是“零”,并且仍然会呈现默认内容,除非我将任何非空白内容放入定义中。 我在Golang repo上发现了这个问题,它在一个游乐场示例中很好地描述了同样的事情: 奇怪的是,这个问题提到它是固定的(如果我理解正确的话,它在1.8.1中着

  • 我有一个函数,它返回一个动态绑定的-本质上,。当然,实际函数要复杂得多,足以让我为它编写测试,最好是清晰的测试。但是以下: 将始终失败,因为将解析为而不是ConT MyType。 是否有一种很好的方法将类型转换为完全限定的类型,或者检查和是否相同(在当前上下文中)?

  • 我正在尝试使用spring连接到LDAP服务器 有关LDAP服务器的可用信息如下: 主机/ip 端口 域名 这是我的密码 然后在另一个类中是身份验证方法 我有以下错误: m. m. a. ExceptionHandlerExceptionResolver:已解决的[org.springframework.ldap.未分类的LdapExctive:在LDAP处理过程中发生了未分类的异常;嵌套的异常j