feat: 0.0.4.2

1、注解新增是否重试完成抛出异常
2、修复重试完成仍然抛出异常

Signed-off-by: byteblogs168 <598092184@qq.com>
This commit is contained in:
byteblogs168 2022-09-30 16:27:50 +08:00
parent 88761f5d56
commit c7aee3538e
6 changed files with 53 additions and 20 deletions

View File

@ -29,7 +29,7 @@ public class TestExistsTransactionalRetryService {
@Autowired
private RemoteService remoteService;
@Retryable(scene = "testSimpleInsert", bizNo = "#name", localTimes = 3)
@Retryable(scene = "testSimpleInsert", bizNo = "#name", localTimes = 3, isThrowException = false)
@Transactional
public String testSimpleInsert(String name) {
@ -50,7 +50,7 @@ public class TestExistsTransactionalRetryService {
Result call = remoteService.call();
System.out.println("-------------->"+call.getMessage());
if (call.getStatus() == 0) {
throw new UnsupportedOperationException("调用远程失败");
throw new UnsupportedOperationException("调用远程失败" + school.getAddress());
}
return "testSimpleInsert"+school.getAddress();

View File

@ -39,7 +39,7 @@ public class ExistsTransactionalRetryServiceTest {
Mockito.when(remoteService.call())
.thenReturn(new Result(0, "1"))
.thenReturn(new Result(0, "2"))
.thenReturn(new Result(0, "3"))
.thenReturn(new Result(1, "3"))
.thenReturn(new Result(0, "4"))
.thenReturn(new Result(0, "5"))
;
@ -47,7 +47,7 @@ public class ExistsTransactionalRetryServiceTest {
String s = testExistsTransactionalRetryService.testSimpleInsert(UUID.randomUUID().toString());
System.out.println(s);
} catch (Exception e) {
log.error("", e);
log.error("重试未成功", e);
}
Thread.sleep(90000);

View File

@ -68,5 +68,16 @@ public @interface Retryable {
*/
int localInterval() default 2;
/**
* 本地重试完成后是否抛出异常
* 如果不抛出异常则调用需要重试方法的方法则感知不到异常信息
*
* 比如: A->B->C->D->E
* D需要重试 若配置D不抛异常,则A->B->C无法感知若有事物则无法回滚
*
* @return true-抛出 false-不抛出
*/
boolean isThrowException() default true;
}

View File

@ -22,8 +22,9 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.lang.reflect.Method;
@ -39,6 +40,7 @@ import java.util.UUID;
@Aspect
@Component
@Slf4j
@Order(PriorityOrdered.HIGHEST_PRECEDENCE + 2)
public class RetryAspect {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@ -69,6 +71,7 @@ public class RetryAspect {
Throwable throwable = null;
Object result = null;
RetryerResultContext retryerResultContext;
try {
result = point.proceed();
} catch (Throwable t) {
@ -77,10 +80,20 @@ public class RetryAspect {
LogUtils.debug("开始进行重试 aop [{}]", traceId);
// 入口则开始处理重试
doHandlerRetry(point, traceId, retryable, executorClassName, methodEntrance, throwable);
retryerResultContext = doHandlerRetry(point, traceId, retryable, executorClassName, methodEntrance, throwable);
}
LogUtils.debug("aop 结果处理 traceId:[{}] result:[{}] ", traceId, result, throwable);
// 若是重试完成了, 则判断是否返回重试完成后的数据
if (Objects.nonNull(retryerResultContext)) {
// 重试成功直接返回结果 若注解配置了isThrowException=false 则不抛出异常
if (retryerResultContext.getRetryResultStatusEnum().getStatus().equals(RetryResultStatusEnum.SUCCESS.getStatus())
|| !retryable.isThrowException()) {
return retryerResultContext.getResult();
}
}
if (throwable != null) {
throw throwable;
} else {
@ -89,7 +102,7 @@ public class RetryAspect {
}
private void doHandlerRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, String methodEntrance, Throwable throwable) {
private RetryerResultContext doHandlerRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, String methodEntrance, Throwable throwable) {
if (!RetrySiteSnapshot.isMethodEntrance(methodEntrance)
|| RetrySiteSnapshot.isRunning()
@ -106,27 +119,30 @@ public class RetryAspect {
RetrySiteSnapshot.isRetryFlow(),
RetrySiteSnapshot.isRetryForStatusCode()
);
return;
return null;
}
if (!TransactionSynchronizationManager.isActualTransactionActive()) {
// 无事务, 开启重试
openRetry(point, traceId, retryable, executorClassName, throwable);
return;
return openRetry(point, traceId, retryable, executorClassName, throwable);
}
// final RetryerResultContext[] retryerResultContext = {null};
// 存在事物
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
// TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
//
// @Override
// public void afterCompletion(int status) {
// // 有事务开启重试
// retryerResultContext[0] = openRetry(point, traceId, retryable, executorClassName, throwable);
// }
// });
@Override
public void afterCompletion(int status) {
// 有事务开启重试
openRetry(point, traceId, retryable, executorClassName, throwable);
}
});
return null;
}
private void openRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, Throwable throwable) {
private RetryerResultContext openRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, Throwable throwable) {
try {
@ -136,6 +152,7 @@ public class RetryAspect {
LogUtils.debug("aop 结果成功 traceId:[{}] result:[{}]", traceId, context.getResult());
}
return context;
} catch (Exception e) {
LogUtils.error("重试组件处理异常,{}", e);
@ -145,6 +162,8 @@ public class RetryAspect {
} finally {
RetrySiteSnapshot.removeAll();
}
return null;
}
private void sendMessage(Exception e) {

View File

@ -76,6 +76,7 @@ public class RetryableScanner implements Scanner, ApplicationContextAware {
int localTimes = retryable.localTimes();
int localInterval = retryable.localInterval();
Class<? extends RetryMethod> retryMethod = retryable.retryMethod();
boolean throwException = retryable.isThrowException();
return new RetryerInfo(retryable.scene(),
executorClassName,
@ -88,7 +89,8 @@ public class RetryableScanner implements Scanner, ApplicationContextAware {
localInterval,
bizIdGenerate,
bizNo,
retryMethod
retryMethod,
throwException
);
}

View File

@ -28,4 +28,5 @@ public class RetryerInfo {
private final Class<? extends BizIdGenerate> bizIdGenerate;
private final String bizNo;
private final Class<? extends RetryMethod> retryMethod;
private final boolean isThrowException;
}