mybatis-plus乐观锁重试机制配置重置次数

1、项目结构
在这里插入图片描述
2、定义异常类
2.1 ApiResultEnum类

package com.example.springbootmybatisplus.common;

public enum ApiResultEnum {
    SUCCESS(200,"ok"),
    FAILED(400,"请求失败"),
    ERROR(500,"服务器错误"),
    ERROR_NULL(501,"空指针异常"),
    ERROR_CLASS_CAST(502,"类型转换异常"),
    ERROR_RUNTION(503,"运行时异常"),
    ERROR_IO(504,"上传文件异常"),
    ERROR_MOTHODNOTSUPPORT(505,"请求方法错误"),
    ERROR_TRY_AGAIN(506,"正在重试"),
    ERROR_TRY_AGAIN_FAILED(507,"重试失败"),
    //参数
    PARAMETER_NULL(10001,"缺少参数或值为空"),
    TRIGGER_GROUP_AND_NAME_SAME(10002,"组名和名称已存在"),
    //账户
    ACCOUNT_LOCK(20001,"账号已锁定"),
    ACCOUNT_NOT_FOUND(20002,"找不到账户信息"),
    ACCOUNT_PASSWARD_ERROR(20003,"用户名密码错误"),
    ACCOUNT_EXIST(20004,"账号已存在"),
    ACCOUNT_NOT_SUFFICIENT(20005,"账号余额不足"),
    //权限
    AUTH_NOT_HAVE(30001,"没有权限"),
    AUTH_SIGN_NOT_MATCH(30002,"签名不匹配"),
    FILE_IS_NULL(40001,"文件为空"),
    FILE_NOT_PIC(40002,"不是图片类型文件"),
    TASK_IS_RUNING(50001,"任务已启动,无法再起启动"),
    TASK_IS_PAUSE(50002,"任务暂停,只可继续执行"),
    TASK_NOT_RUNING(50003,"任务未执行,无法暂停"),
    EMS_CODE_NOT_FOUND(60000,"物流编号找不到,请填写物流编号"),
    ;
    private int status;
    private String message;

    public String getMessage() {
        return message;
    }
    public int getStatus() {
        return status;
    }
    private ApiResultEnum(int status,String message) {
        this.status = status;
        this.message = message;
    }
}

2.2 ApiException类

package com.example.springbootmybatisplus.common;

public class ApiException extends RuntimeException {
    private static final long serialVersionUID = 1L;
    private int status;
    private String message;
    private Object data;
    private Exception exception;
    public ApiException() {
        super();
    }

    public ApiException(String message) {
        super(message);
        this.message=message;
    }

    public ApiException(int status, String message, Object data, Exception exception) {
        super(message,exception);
        this.status = status;
        this.message = message;
        this.data = data;
        this.exception = exception;
    }
    public ApiException(ApiResultEnum apiResultEnum) {
        this(apiResultEnum.getStatus(),apiResultEnum.getMessage(),null,null);
    }
    public ApiException(ApiResultEnum apiResultEnum, Object data) {
        this(apiResultEnum.getStatus(),apiResultEnum.getMessage(),data,null);
    }
    public ApiException(ApiResultEnum apiResultEnum, Object data, Exception exception) {
        this(apiResultEnum.getStatus(),apiResultEnum.getMessage(),data,exception);
    }
}

3、定义注解切面
3.1 注解IsTryAgain

package com.example.springbootmybatisplus.isTryAgainConfig;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface IsTryAgain {
}

3.2 定义异常TryAgainException类

package com.example.springbootmybatisplus.isTryAgainConfig;

import com.example.springbootmybatisplus.common.ApiException;
import com.example.springbootmybatisplus.common.ApiResultEnum;

public class TryAgainException extends ApiException {
    public TryAgainException(ApiResultEnum apiResultEnum) {
        super(apiResultEnum);
    }
}

3.3 定义切面TryAgainAspect类

package com.example.springbootmybatisplus.isTryAgainConfig;

import com.example.springbootmybatisplus.common.ApiException;
import com.example.springbootmybatisplus.common.ApiResultEnum;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.transaction.annotation.Transactional;

@Aspect
@Configuration
public class TryAgainAspect implements Ordered {
    /**
     * 默认重试几次
     */
    private static final int DEFAULT_MAX_RETRIES = 3;

    private int maxRetries = DEFAULT_MAX_RETRIES;
    private int order = 1;

    public void setMaxRetries(int maxRetries) {
        this.maxRetries = maxRetries;
    }

    public int getOrder() {
        return this.order;
    }

    @Pointcut("@annotation(IsTryAgain)")
    public void retryOnOptFailure() {
        // pointcut mark
    }

    @Around("retryOnOptFailure()")
    @Transactional(rollbackFor = Exception.class)
    public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {
        int numAttempts = 0;
        do {
            numAttempts++;
            try {
                //再次执行业务代码、
                Object proceed = pjp.proceed();
                System.out.println("==重试成功==");
                return proceed;
            } catch (TryAgainException ex) {
                if (numAttempts > maxRetries) {
                    //log failure information, and throw exception
//					如果大于 默认的重试机制 次数,我们这回就真正的抛出去了
                    throw new ApiException(ApiResultEnum.ERROR_TRY_AGAIN_FAILED);
                }else{
                    //如果 没达到最大的重试次数,将再次执行
                    System.out.println("=====正在重试====="+numAttempts+"次");
                }
            }
        } while (numAttempts <= this.maxRetries);
        return null;
    }
}

4、在service层使用@IsTryAgain注解并抛出异常,例如

@IsTryAgain
    public String updateUser(User user) throws Exception{
        Integer version=userMapper.selectById(user.getId()).getVersion();
        user.setVersion(version);
        userMapper.updateById(user);
        return "OK";
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员阿明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值