问题
The following code is not retrying. What am I missing?
@EnableRetry
@SpringBootApplication
public class App implements CommandLineRunner
{
.........
.........
@Retryable()
ResponseEntity<String> authenticate(RestTemplate restTemplate, HttpEntity<MultiValueMap<String, String>> entity) throws Exception
{
System.out.println("try!");
throw new Exception();
//return restTemplate.exchange(auth_endpoint, HttpMethod.POST, entity, String.class);
}
I have added the following to the pom.xml.
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
I also tried providing different combinations of arguments to @Retryable.
@Retryable(maxAttempts=10,value=Exception.class,backoff=@Backoff(delay = 2000,multiplier=2))
Thanks.
回答1:
In spring boot 2.0.2 Release, I have observed that the @Retryable is not working if you have retryable and called method in same class. On debugging found that the pointcut is not getting built properly. For now, the workaround for this problem is that we need to write the method in a different class and call it.
Working Example could be found here.
回答2:
For the @Retryable
annotation on the method to be discovered it needs to be called correctly from an initialised context. Is the method invoked from a bean from the spring context or called by other means?
If testing this is your runner using the SpringJunit4ClassRunner
?
回答3:
I solved it. I figured out that if return something from the method that you trying to retry, then @Retryable() is not working.
maven dependency in pom.xml
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.5.RELEASE</version>
</dependency>
Spring boot Application.java
@SpringBootApplication
@EnableTransactionManagement
@EnableRetry
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
in controller.java
@RestController
public class JavaAllDataTypeController {
@Autowired
JavaAllDataTypeService JavaAllDataTypeService;
@RequestMapping(
value = "/springReTryTest",
method = RequestMethod.GET
)
public ResponseEntity<String> springReTryTest() {
System.out.println("springReTryTest controller");
try {
JavaAllDataTypeService.springReTryTest();
} catch (Exception e) {
e.printStackTrace();
}
return new ResponseEntity<String>("abcd", HttpStatus.OK);
}
}
in service.java
@Service
@Transactional
public class JavaAllDataTypeService {
// try the method 9 times with 2 seconds delay.
@Retryable(maxAttempts=9,value=Exception.class,backoff=@Backoff(delay = 2000))
public void springReTryTest() throws Exception {
System.out.println("try!");
throw new Exception();
}
}
output: It' trying 9 times then throwing exception.
回答4:
It work for return type as well
@Service
public class RetryService {
private int count = 0;
// try the method 9 times with 2 seconds delay.
@Retryable(maxAttempts = 9, value = Exception.class, backoff = @Backoff(delay = 2000))
public String springReTryTest() throws Exception {
count++;
System.out.println("try!");
if (count < 4)
throw new Exception();
else
return "bla";
}
}
回答5:
I had exactly the same issue as described in the original question.
In my case it turned out that the spring-boot-starter-aop
dependency was accidentally not included. After adding it to my pom.xml
, my @Retryable
methods worked as expected.
Returning values from @Retryable
methods works fine for me.
回答6:
An alternative could be RetryTemplate
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(2000l);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(2);
retryTemplate.setRetryPolicy(retryPolicy);
return retryTemplate;
}
and
retryTemplate.execute(new RetryCallback<Void, RuntimeException>() {
@Override
public Void doWithRetry(RetryContext arg0) {
myService.templateRetryService();
...
}
});
worked out for me
source
来源:https://stackoverflow.com/questions/38212471/springboot-retryable-not-retrying