赞
踩
在用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(); }
做支付的时候,接口被调用了两次,第一次还没有执行完,点了第二次,此时第二次获取不到锁,理想情况下要抛出异常“请不要频繁发起付款”,但是报了错 “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(); } }
只需要在finally 里面判定是否是当前线程的锁,如果是在进行解锁就好了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。