一、乐观锁失败后会报:ObjectOptimisticLockFailureExceptionjava
二、处理方案:捕获到对应乐观锁失败异常后进行重试
以下使用aop实现一个重试,可用于乐观锁
1、新建一个注解,用于标注需要重试的方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RetryOnOptimisticLockingFailure {
}
2、新建重试的方法并添加注解
public interface UserService {
int save();
}
@Service
public class UserServiceImpl implements UserService{
@Override
@RetryOnFail //添加重试注解
public int save() {
int i = new Random().nextInt(10);
int i1 = 10 / (i % 3); //除0异常 这里模拟乐观异常
return i1;
}
}
3、新建切面类对标注注解的方法进行代理
@Component
@Aspect
public class RetryOnOptimisticLockingFailureAspect {
//定义最大重试次数
private final int MAX_RETRY_TIME=5;
//基于注解定义切入点 --这里要写刚刚定义那个注解的全限定名
@Pointcut("@annotation(com.example.service.RetryOnOptimisticLockingFailure)")
public void retryOnOptFailure(){}
//定义通知
@Around("retryOnOptFailure()")
public Object doProceed(ProceedingJoinPoint joinPoint) throws Throwable {
int time=0;
do {//循环5次
time++;
try {
Object proceed = joinPoint.proceed();
return proceed;//如果没有异常则正常返回结束循环与方法
} catch (Exception e) {
//出异常了,记录log,进入循环
if(e instanceof ArithmeticException){//修改对应的异常 如:乐观锁OptimisticLockingException
System.out.println("retrying....times:"+time);
}
}
} while (time<MAX_RETRY_TIME);
return null;
}
}
4、测试
@SpringBootTest
public class MyTest {
@Autowired
private UserService userService;
@Test
public void save(){
for (int i = 0; i < 10; i++) {//调用10次 增加触发重试的机率
System.out.println(userService.save());
}
}
}
5、运行结果