事务重复执行导致redis锁并发获取数据异常

背景

在事务函数触发的时候添加锁,函数执行完释放锁之后,此时事务还没提交,但是由于锁释放了,此时调用get函数获取的数据还是旧的。

触发代码

如下refreshBusinessFoodCount函数中,并发请求两次,第二次get获取的数据还是旧数据(尽管添加了并发锁注解@ConcurrenLock)

@Transactional(rollbackFor = Exception.class)
@ConcurrenLock
public void refreshBusinessFoodCount() {
	get();
	save();
}

@Aspect
@Component
@Slf4j
@Order(0)
public class ConcurrentLockAspect {

    @Autowired
    private RedissonUtil redissonUtil;



    @Around("@annotation(com.meal.annotation.appbusiness.ConcurrenLock)")
    public Object methodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        ConcurrenLock annotation = signature.getMethod().getAnnotation(ConcurrenLock.class);
        String lockKey = annotation.lockKey();
        if(StringUtils.isEmpty(lockKey)) {
            lockKey = Constant.REDIS_LISTENER_CONCURRENT_LOCK+signature.getName()+":";
        }
        Integer lockTime = annotation.lockTime();

        try {
            this.redissonUtil.lock(lockKey, lockTime);//锁一分钟

            Object[] args = joinPoint.getArgs();
            // 执行目标方法
            return joinPoint.proceed(args);

        }catch (Exception e){
            e.printStackTrace();
            throw e;
        } finally {
            if(this.redissonUtil.isLocked(lockKey))
                this.redissonUtil.unlock(lockKey);
        }

    }


}

原因

  1. ConcurrenLock切面触发必须要在Transactional切面触发之前
  2. ShiroConfig的配置中引入了DefaultAdvisorAutoProxyCreator会导致Transactional多次代理,然后函数执行时会重复执行事务。

解决方法

  1. 注释掉shiroconfig的DefaultAdvisorAutoProxyCreator 配置
//    @Bean
//    @DependsOn(value = "lifecycleBeanPostProcessor")
//    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
//        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
//        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
//        return defaultAdvisorAutoProxyCreator;
//    }
  1. ConcurrentLockAspect增加@Order(0)注解,把优先级调高,让代理在Transactional的代理之前执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序资源库

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

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

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

打赏作者

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

抵扣说明:

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

余额充值