在重试未触发时调用Springboot @retryable listeners



我正在使用@Retryable,就像下面我在服务类中重试db保存函数一样。我想撤销重审。但是重试函数总是在侦听器中调用。

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);
}

}

我有一个这样的监听器,它被传递给@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);
}
}

现在我从另一个组件类调用服务类方法。

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();
}
}

}

现在的问题是,onError(), close(), open()正在被调用,即使没有重试。我看到类似这样的输出重试情况和非重试情况。

adding people
Exception Occurred, Retry Session Started
Hibernate:
insert
into
people
(age, first_name, last_name)
values
(?, ?, ?)
Unable to recover from  Exception
Error

一些链接:

  1. RetryListener医生

  2. 完整代码在这里

总是调用open()close()

这是完全错误的:

@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);
}
/**
* Called before the first attempt in a retry. For instance, implementers can set up
* state that is needed by the policies in the {@link RetryOperations}. The whole
* retry can be vetoed by returning false from this method, in which case a
* {@link TerminatedRetryException} will be thrown.
* @param <T> the type of object returned by the callback
* @param <E> the type of exception it declares may be thrown
* @param context the current {@link RetryContext}.
* @param callback the current {@link RetryCallback}.
* @return true if the retry should proceed.
*/

close也一样。

System.out.println("Unable to recover from  Exception");

这不是close()的意思。

最新更新