I am using @Retryable like following where I am retrying a db save function in a service class. I want to tract the retrying. But the retry functions are always invoked in the listener.
PeopleService.java
package com.test.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.beans.factory.annotation.Autowired;
@Service
public class PeopleService {
@Autowired
private PeopleRepository peopleRepository;
@Retryable(value = {Exception.class}, maxAttempts = 3,
backoff = @Backoff(delay = 200), listeners = {"retryListener"})
public void addPeople() throws Exception{
People p = new People(20, "James", "bond");
peopleRepository.save(p);
}
}
I have a listener like this which was passed to listener in @Retryable.
RetryListener.java
package com.test.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.listener.RetryListenerSupport;
import org.springframework.stereotype.Component;
@Slf4j
@Component
class RetryListener extends RetryListenerSupport {
@Override
public <T, E extends Throwable> void close(RetryContext context,
RetryCallback<T, E> callback, Throwable throwable) {
System.out.println("Unable to recover from Exception");
System.out.println("Error ");
super.close(context, callback, throwable);
}
@Override
public <T, E extends Throwable> void onError(RetryContext context,
RetryCallback<T, E> callback, Throwable throwable) {
System.out.println("Exception Occurred, Retry Count " + context.getRetryCount());
super.onError(context, callback, throwable);
}
@Override
public <T, E extends Throwable> boolean open(RetryContext context,
RetryCallback<T, E> callback) {
System.out.println("Exception Occurred, Retry Session Started ");
return super.open(context, callback);
}
}
Now I am calling the service class method from another component class.
Demo.java
package com.test.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.beans.factory.annotation.Autowired;
@Slf4j
@Component
public class Demo {
@Autowired
private PeopleService peopleService;
@Scheduled(initialDelay = 5000L, fixedDelay = 1000L)
private void perMinuteStatsTask() {
try {
System.out.println("adding people");
peopleService.addPeople();
}catch(Exception ex)
{
ex.printStackTrace();
}
}
}
Now the thing is, the onError(), close(), open() is being called even if there is no retry. I am seeing something like this as output for retry case and also for non-retry case.
adding people
Exception Occurred, Retry Session Started
Hibernate:
insert
into
people
(age, first_name, last_name)
values
(?, ?, ?)
Unable to recover from Exception
Error
some links: