当前位置:   article > 正文

【Java】 attempt to unlock lock, not locked by current thread原因以及解决办法

attempt to unlock lock, not locked by current thread

前言

在用redisson 下来锁做接口防抖(重复提交)的时候,发现报了“attempt to unlock lock, not locked by current thread”这个错,这里简单分析一下原因,以及给出解决方案。

问题伪代码
        RLock lock = redissonClient.getLock("业务编号");
        log.info("图文问诊患者去支付入参:{}", JsonUtil.toJson(param));
        try {
            if (lock.tryLock(0, 30, TimeUnit.SECONDS)) {
            	// 业务流程
            } else {
                log.info("userCode:{},patientCode:{},doctorCode:{},请勿频繁发起付款!", param.getUserCode(), param.getPatientCode(), param.getDoctorCode());
                throw new BizException("请不要频繁发起付款");
            }
        } catch (BizException e) {
            log.error("图文问诊去支付异常:{}", e.getMessage());
            throw e;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
          lock.unlock();
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
代码功能简单说明:

做支付的时候,接口被调用了两次,第一次还没有执行完,点了第二次,此时第二次获取不到锁,理想情况下要抛出异常“请不要频繁发起付款”,但是报了错 “attempt to unlock lock, not locked by current thread”,这是因为第二次进来没有获取到锁,直接进去到了finally,执行了 lock.unlock(),第二个请求尝试解锁一个没有被当前线程锁定的锁

解决办法
      RLock lock = redissonClient.getLock("业务编号");
        log.info("图文问诊患者去支付入参:{}", JsonUtil.toJson(param));
        try {
            if (lock.tryLock(0, 30, TimeUnit.SECONDS)) {
            	// 业务流程
            } else {
                log.info("userCode:{},patientCode:{},doctorCode:{},请勿频繁发起付款!", param.getUserCode(), param.getPatientCode(), param.getDoctorCode());
                throw new BizException("请不要频繁发起付款");
            }
        } catch (BizException e) {
            log.error("图文问诊去支付异常:{}", e.getMessage());
            throw e;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
          // 解锁前检查当前线程是否持有该锁
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

只需要在finally 里面判定是否是当前线程的锁,如果是在进行解锁就好了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/1009018
推荐阅读
相关标签
  

闽ICP备14008679号