java-业务加锁

给业务加锁:
背景: 有些业务需要加锁,避免多个用户同时操作,比如10个用户同时点击修改某条数据。
方案:使用redis 进行加锁。redis缓存使用
步骤:
一:加锁

    public boolean tryLock(String employeeId,String uuid) {
        String judge=jedisUtil.setNX("PUSH_CONTRACT_BY_ID_"+employeeId,uuid,5000);
        //获得锁成功
        if("OK".equals(judge)) {
            return true;
        }
        return false;
    }

二:释放锁

  public boolean releaseLock(String key, String value)
  {
    Jedis jedis = getJedis();
    String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value));
    jedis.close();
    return RELEASE_SUCCESS.equals(result);
  }

三:使用案例一

           //合同推送的整个处理过程加锁处理
            String uuid = UUID.randomUUID().toString();
            if (tryLock(employeeId,uuid)){
                EmployeeInformation employeeInformation = employeeInformationService.findById(employeeId);
                //已推送的不再推送
                if (employeeInformation == null || (PushStatus.PUSH_SUCCESS.getCode().equals(employeeInformation.getPushStatus()))){
                    return;
                }
                String validIdentityId = employeeInformation.getValidIdentityId();
                UserIdentity userIdetity = userIdentityService.findByIdentityCardId(validIdentityId);
                //员工未实名或当前员工信息为编辑中状态时推送失败
                if (userIdetity == null || EditStatus.EDIT.getStatusCode().equals(employeeInformation.getEditStatus())) {
                    logger.error("员工[{}]还未在app端进行实名或合同处于编辑中状态无法推送,合同推送失败",employeeInformation.getName());
                    //员工还未实名认证时,把该条记录置为推送失败
                    employeeInformation.setPushStatus(PushStatus.PUSH_FAILED.getCode());
                    employeeInformationService.updateById(employeeInformation);
                    return;
                }
                //推送合同
                boolean pushComplete;
                List<Notification> list = new ArrayList<>();
                User user = userService.findOne(userIdetity.getUserId());
                if (EmployeeMatchAction.CUSTOMLAUNCH.equals(employeeInformation.getMatchAct())){
                    //自定义合同推送
                    pushComplete = customContractPushProcess(employeeInformation,userIdetity,user,list,jMePushMsgs);
                }else {
                    //模板合同推送
                    pushComplete = templateContractPushProcess(employeeInformation,userIdetity,user,list,jMePushMsgs);
                }
                //推送完成后修改员工信息状态为已推送
                if (pushComplete){
                    employeeInformation.setPushStatus(PushStatus.PUSH_SUCCESS.getCode());
                    employeeInformationService.updateById(employeeInformation);
                    //所有合同推送成功,批量插入站内通知
                    notificationService.batchAddAppNotice(list);
                    //成功推送的人数+1
                    successNum.getAndIncrement();
                }else {
                    //推送失败的情况的下可能存在已经有推送成功的合同,所以需要删除该员工信息下推送成功的合同
                    deleteContractsByEmployeeId(employeeId);
                }
                //员工所属的分区与员工信息所属分区不一致时,需要更新员工的所属分区
                if (!employeeInformation.getPartitionId().equals(user.getPartitionId())){
                    user.setPartitionId(employeeInformation.getPartitionId());
                    userService.update(user);
                }
                jedisUtil.releaseLock("PUSH_CONTRACT_BY_ID_"+employeeId,uuid);
            }

四使用案例二

       /**
         * 跨区印章申请审核
         * 1.加锁,审核信息id作为锁,同一条记录同时只能有一个人操作
         * 2.包含一个跨区印章,其操作结果直接影响合同审核状态
         * 3.包含两个及两个以上都是跨区印章
         *   2.1 再加锁合同id锁,合同同时只能被一人更新
         *   2.2 当所有审核均通过时,更新合同审核状态为通过
         *   2.3 驳回操作只会影响本条记录及合同审核状态,其它已审核过的不受影响
         */
        try{
            boolean lock = jedisLockUtil.tryLock(RedisPreKey.EXAMINE_RECORD_ID_PRFIX + req.getId(), NumberEnum.ONE.getNumberStr(), 3000);
            if(!lock){
                throw new SSCSignException(BaseConstants.ALREADY_OTHERS_OPERATER_CODE,BaseConstants.ALREADY_OTHERS_OPERATER_MSG);
            }
            Examine examine = selectById(req.getId());
            if(examine == null || !ExamineStatusEnum.WAIT_EXAMINE.getStatusCode().equals(examine.getExamineStatus())){
                throw new SSCSignException(BaseConstants.ALREADY_OTHERS_OPERATER_CODE,BaseConstants.ALREADY_OTHERS_OPERATER_MSG);
            }
            Contract contract = contractService.selectById(examine.getContractId());
            if(contract==null){
                //当合同已被删除,该条待审批记录自动清除
                examineMapper.deleteByPrimaryKey(examine.getId());
                throw new SSCSignException(Constants.CONTRACT_ALREADY_DELETED_CODE,Constants.CONTRACT_ALREADY_DELETED_MSG);
            }
            if(contract.getSealNum()==1){
                singleWaitSignSealExamineHandler(req,examine,contract,userInfo);
            }
            if(contract.getSealNum()>1){
                String[] sealPartitionIdArr = contract.getSealPartitionIds().split(",");
                String[] sealIdArr = contract.getSealIds().split(",");
                ArrayList<String> crossPartitionSealIdList = new ArrayList<>();
                for (int i=0;i<sealPartitionIdArr.length;i++) {
                    if(!contract.getPartitionId().equals(Integer.parseInt(sealPartitionIdArr[i]))){
                        crossPartitionSealIdList.add(sealIdArr[i]);
                    }
                }
                if(crossPartitionSealIdList.size()==1){
                    singleWaitSignSealExamineHandler(req,examine,contract,userInfo);
                }else{
                    try{
                        //加合同id锁
                        lock = jedisLockUtil.tryLock(RedisPreKey.CROSS_SEAL_EXAMINE_CONTRACT_ID_PRFIX + contract.getId(), "1", 3000);
                        if(!lock){
                            throw new SSCSignException(BaseConstants.DOING_PROCESS_BY_OTHERS_CODE,BaseConstants.DOING_PROCESS_BY_OTHERS_MSG);
                        }
                        multipleWaitSignSealExamineHandler(req,examine,contract,userInfo,crossPartitionSealIdList);
                    }finally {
                        jedisLockUtil.releaseLock(RedisPreKey.CROSS_SEAL_EXAMINE_CONTRACT_ID_PRFIX + contract.getId(), NumberEnum.ONE.getNumberStr());
                    }
                }
            }
        }finally {
            jedisLockUtil.releaseLock(RedisPreKey.EXAMINE_RECORD_ID_PRFIX + req.getId(), NumberEnum.ONE.getNumberStr());
        }
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值