-
Notifications
You must be signed in to change notification settings - Fork 519
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combining @Retryable and @Scheduled cause scheduled execution problems #94
Comments
What Spring Framework and Spring Retry versions are you using? It works fine for me with boot 1.5.8 (spring 4.3.12 and retry 1.2.1). It works with both CGLIB and JDK proxies too; the latter works with the annotation on either the bean or the interface). JDK: @SpringBootApplication
@EnableScheduling
@EnableRetry
public class RetryGh94Application {
public static void main(String[] args) {
SpringApplication.run(RetryGh94Application.class, args)
.close();
}
@Bean
public ApplicationRunner runner(MyBean bean) throws Exception {
System.out.println(bean.getClass());
return args -> {
try {
bean.retry();
}
catch (Exception e) {
//
}
Thread.sleep(30_000);
};
}
@Bean
public MyBean bean() {
return new MyBeanImpl();
}
public interface MyBean {
// @Scheduled(fixedDelay = 5000)
void sched();
// @Retryable(maxAttempts = 3)
void retry();
}
public static class MyBeanImpl implements MyBean {
@Override
@Scheduled(fixedDelay = 5000)
public void sched() {
System.out.println("sched");
}
@Override
@Retryable(maxAttempts = 3)
public void retry() {
System.out.println("retry");
throw new RuntimeException("foo");
}
}
} CGLIB: @SpringBootApplication
@EnableScheduling
@EnableRetry
public class RetryGh94Application {
public static void main(String[] args) {
SpringApplication.run(RetryGh94Application.class, args)
.close();
}
@Bean
public ApplicationRunner runner(MyBean bean) throws Exception {
System.out.println(bean.getClass());
return args -> {
try {
bean.retry();
}
catch (Exception e) {
//
}
Thread.sleep(30_000);
};
}
@Bean
public MyBean bean() {
return new MyBean();
}
public static class MyBean {
@Scheduled(fixedDelay = 5000)
public void sched() {
System.out.println("sched");
}
@Retryable(maxAttempts = 3)
public void retry() {
System.out.println("retry");
throw new RuntimeException("foo");
}
}
} |
Strange. I'm using spring-retry 1.2.1.RELEASE and spring-boot 1.5.5-RELEASE. I will try to use 1.5.8 and maybe in a freshly created new project to eliminate potential side effects and give you feedback. Thank you for your quick response. |
The same project with spring-boot 1.5.8 has the same problem, as long as I remove the @retryable annotation it starts to work. I will create a fresh project and evolve it to my original project until I find the root cause. It will take some time, but I will come back 😄 |
I was wondering if it has something to do with the order in which the BPPs are run. I got the reverse problem (sched but no retry) when the bean was already a proxy and was forced to put the annotations on the interface (JDK proxy) to make it work... @SpringBootApplication
@EnableRetry
@EnableScheduling
public class RetryGh94Application {
public static void main(String[] args) {
SpringApplication.run(RetryGh94Application.class, args)
.close();
}
@Bean
public ApplicationRunner runner(MyBean bean) throws Exception {
System.out.println(bean.getClass());
return args -> {
try {
bean.retry();
}
catch (Exception e) {
//
}
Thread.sleep(30_000);
};
}
@Bean
public MyBean bean() {
MyBeanImpl myBeanImpl = new MyBeanImpl();
ProxyFactory factory = new ProxyFactory(myBeanImpl);
return (MyBean) factory.getProxy();
}
public interface MyBean {
@Scheduled(fixedDelay = 5000)
void sched();
@Retryable(maxAttempts = 3)
void retry();
}
public static class MyBeanImpl implements MyBean {
@Override
@Scheduled(fixedDelay = 5000)
public void sched() {
System.out.println("sched");
}
@Override
@Retryable(maxAttempts = 3)
public void retry() {
System.out.println("retry");
throw new RuntimeException("foo");
}
}
} I was able to reproduce your condition (retry but no sched) with CGLIB proxies... @SpringBootApplication
@EnableRetry(proxyTargetClass = true)
@EnableScheduling
public class RetryGh94Application {
public static void main(String[] args) {
SpringApplication.run(RetryGh94Application.class, args)
.close();
}
@Bean
public ApplicationRunner runner(MyBean bean) throws Exception {
System.out.println(bean.getClass());
return args -> {
try {
bean.retry();
}
catch (Exception e) {
//
}
Thread.sleep(30_000);
};
}
@Bean
public MyBean bean() {
MyBean myBeanImpl = new MyBean();
ProxyFactory factory = new ProxyFactory(myBeanImpl);
factory.setProxyTargetClass(true);
return (MyBean) factory.getProxy();
}
public static class MyBean {
@Scheduled(fixedDelay = 5000)
public void sched() {
System.out.println("sched");
}
@Retryable(maxAttempts = 3)
public void retry() {
System.out.println("retry");
throw new RuntimeException("foo");
}
}
} So it looks like it might be an issue with the A work around should be possible if you add an interface and use JDK proxies. |
Thank you for your comprehensive response. I just created a ticket in JIRA. Here is the link: https://jira.spring.io/browse/SPR-16196 |
Hi @garyrussell, you can mark this issue as resolved since SPR-16196 is fixed now. Thank you. |
Hi @garyrussell , I am facing a similar issue where I have used @scheduled with cron expression to schedule my job to run once a day at a particular time. I need to retry it in case of an exception which I configured using @retryable. This is my first time using @retryable annotation. I took help from http://www.baeldung.com/spring-retry. But it just won't retry the job after 5000 milliseconds which I configured using delay parm. Is it possible to use both of these annotations for same method? The only difference between this post and my implementation is that I am trying to use it for a method while this post is using two. Please let me know if you need to take a look at sample code and I will make some. Thank you! |
Please don't piggy-back on existing (closed) issues. Are you using Spring 5.0.3 or higher (or 4.3.14 or higher) as noted as the fix versions on SPR-16196. The current version of spring-retry is 1.2.2.RELEASE. I just tested with this and it worked just fine... @SpringBootApplication
@EnableRetry
@EnableScheduling
public class Gitter27Application {
public static void main(String[] args) {
SpringApplication.run(Gitter27Application.class, args);
}
@Retryable
@Scheduled(fixedDelay = 5000)
public void Foo() {
System.out.println("here");
throw new RuntimeException("foo");
}
} |
Using @retryable in @service at method level which is going to retry 3 times by default if get any exception and @recover responsible to sa error count in postgres database table. |
Hi,
if I use @retryable annotation for a method of a certain bean and @scheduled for another method of the same bean, ScheduledAnnotationBeanPostProcessor doesn't process this class and thus @scheduled method is not executed. This is a very strange problem.
If I remove the @retryable annotation, ScheduledAnnotationBeanPostProcessor process the bean with processScheduled() method and the scheduled task is executed without any problem.
I don't really understand which part of the framework (scheduling or retry) is responsible for this problem.
Thanks.
The text was updated successfully, but these errors were encountered: