java retry_Retry重试机制

对于重试机制有两个一个是Guava,另一个是spring的。

Guava retryer工具

pom引用

com.github.rholder

guava-retrying

2.0.0

测试方法

Retryer retryer = RetryerBuilder.newBuilder()

.retryIfExceptionOfType(Exception.class)

//返回false也需要重试

.retryIfResult(Predicates.equalTo(false))

//重调策略

.withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))

//尝试次数

.withStopStrategy(StopStrategies.stopAfterAttempt(3))

.build();

try {

//执行指定的方法。

retryer.call(() -> {

System.err.println("do something...");

throw new Exception("我是一个异常!");

});

} catch (ExecutionException e) {

e.printStackTrace();

} catch (RetryException e) {

e.printStackTrace();

}

测试结果

do something...

do something...

do something...

com.github.rholder.retry.RetryException: Retrying failed to complete successfully after 3 attempts.

at com.github.rholder.retry.Retryer.call(Retryer.java:174)

at com.utils.UtilsTest.retryTest(UtilsTest.java:46)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)

at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)

at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)

at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)

at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)

at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)

at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)

at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)

at org.junit.runners.ParentRunner.run(ParentRunner.java:363)

at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)

at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)

at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)

at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)

at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: java.lang.Exception: 我是一个异常!

at com.utils.UtilsTest.lambda$retryTest$0(UtilsTest.java:48)

at com.github.rholder.retry.AttemptTimeLimiters$NoAttemptTimeLimit.call(AttemptTimeLimiters.java:78)

at com.github.rholder.retry.Retryer.call(Retryer.java:160)

... 29 more

扩展介绍

TODO...

spring-retry

pom

引入Spring-retry和aspectjweaver的依赖

org.springframework.retry

spring-retry

org.aspectj

aspectjweaver

修改启动类

需要在启动类上加入@EnableRetry注解

需要重试的方法

在需要重试的方法上加入

@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))

@Retryable的参数说明

value:抛出指定异常才会重试

include:和value一样,默认为空,当exclude也为空时,默认所以异常

exclude:指定不处理的异常

maxAttempts:最大重试次数,默认3次

backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,乐观锁重试机制通常用于解决多线程并发操作同一数据时可能出现的数据冲突问题。乐观锁是指在进行并发操作时,假设数据不会被其他线程修改,因此不会进行加锁,而是在更新数据时使用版本号(或时间戳)进行标识,以确保数据更新顺序的正确性。 乐观锁重试机制的基本思路是在更新数据时,先读取数据的版本号,然后进行更新操作。如果更新过程中发现版本号已经被其他线程修改,则说明数据已经被其他线程更新,此时需要进行重试操作,即重新读取数据的最新版本号,再进行更新操作。重试操作可以重复执行一定次数,直到数据更新成功或达到最大重试次数为止。 在Java中,乐观锁重试机制通常使用CAS操作(Compare And Swap)进行实现,CAS操作是一种无锁算法,它通过比较内存中的值和预期值是否相等来判断是否需要更新内存中的值,从而避免了使用锁的开销和风险。 下面是一个使用乐观锁重试机制的示例代码: ```java public class OptimisticLockDemo { private int value; private int version; public synchronized void update(int newValue) { int retryCount = 0; while (retryCount < MAX_RETRY_COUNT) { int currentVersion = version; if (compareAndSet(currentVersion, newValue, currentVersion + 1)) { return; } retryCount++; } throw new RuntimeException("Update failed after " + MAX_RETRY_COUNT + " retries."); } private boolean compareAndSet(int expectedVersion, int newValue, int newVersion) { synchronized (this) { if (version == expectedVersion) { value = newValue; version = newVersion; return true; } return false; } } } ``` 在这个示例代码中,我们使用了一个value变量来存储数据,一个version变量来存储版本号。在update方法中,我们使用了一个while循环来进行重试操作,如果重试次数超过了最大重试次数,则抛出异常。在compareAndSet方法中,我们使用了synchronized关键字来保证原子性,通过比较version值和expectedVersion值是否相等来判断是否需要进行更新操作。如果需要更新操作,则使用CAS操作来更新value和version的值。 需要注意的是,乐观锁重试机制并不是万能的,它只适用于并发更新操作比较少、冲突概率较低的情况。如果并发更新操作比较频繁、冲突概率较高,则可能会导致重试次数过多,影响性能。此时,建议使用悲观锁机制来保证数据的一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值