redis实现生成自增编码两种方式

思路:都是从缓存中取,取出来+1 再放入缓存,以便下次取用
区别:方式一,手动+1; 方式二:利用 redis.increment 实现自增;
提示:写业务代码时,记得加锁,锁中包含事务;

方式一


    /**
     * 生成经销商任务单号
     *
     * @param custTaskType 经销商任务单类型
     * @return 结果
     */
    @Override
    public ServiceResponse generateCustTaskIdByTaskType(String custTaskType) {
        if (StringUtils.isEmpty(custTaskType)){
            return ServiceResponse.fail("经销商-传入空任务单类型!");
        }
        if (!(custTaskType.toUpperCase().equals(WorkTaskType.客户上市.value())
            || custTaskType.toUpperCase().equals(WorkTaskType.客户基础信息变更.value())
            || custTaskType.toUpperCase().equals(WorkTaskType.客户更名.value())
            || custTaskType.toUpperCase().equals(WorkTaskType.客户扩充.value())
            || custTaskType.toUpperCase().equals(WorkTaskType.基地对外客户上市.value()))){
            return ServiceResponse.fail("经销商-传入任务单类型异常!");
        }
        // 生成编码
        String custTaskId;
        String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String upCustTaskType = custTaskType.toUpperCase();
        String custTaskNoKey = "cust:" + "work_task_no_key" + today + ":" + upCustTaskType;
        Long taskSerialNo = Convert.toLong(redisTemplate.opsForValue().get(custTaskNoKey));
        if (null != taskSerialNo){
            taskSerialNo = taskSerialNo + 1L;
        }else {
            String firstCustTaskId = upCustTaskType + today + "0001";
            if (null == tnWorkTaskMapper.selectTnWorkTaskByTaskId(firstCustTaskId)){
                taskSerialNo = 1L;
            }else {
                // 缓存被意外删除
                List<TnWorkTask> tnWorkTaskList = tnWorkTaskMapper.selectTnWorkTaskList(new TnWorkTask(){{ setTaskType(upCustTaskType);}});
                List<Long> longList = new ArrayList<>();
                tnWorkTaskList.stream().map(TnWorkTask::getTaskId).forEach(e -> longList.add( Convert.toLong(e.substring(12))));
                Long lastTaskNo = longList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0);
                taskSerialNo = lastTaskNo + 1L;
            }
        }
        custTaskId = upCustTaskType + today + (taskSerialNo.toString().length() < 4 ? String.format("%04d", taskSerialNo) : taskSerialNo.toString());
        // 校验
        if (null != tnWorkTaskMapper.selectTnWorkTaskByTaskId(custTaskId)){
            return ServiceResponse.fail("经销商-生成任务单号已存在!");
        }
        redisTemplate.opsForValue().set(custTaskNoKey, taskSerialNo, getSeconds(), TimeUnit.SECONDS);
        return ServiceResponse.success(custTaskId);
    }

    /**
     * 获取当天结束还剩余多少秒
     * @return
     */
    public static int getSeconds(){
        Calendar curDate = Calendar.getInstance();
        Calendar tommorowDate = new GregorianCalendar(
                curDate.get(Calendar.YEAR),
                curDate.get(Calendar.MONTH),
                curDate.get(Calendar.DATE) + 1,
                0, 0, 0);
        return (int)(tommorowDate.getTimeInMillis() - curDate.getTimeInMillis()) / 1000;
    }



方式二


    /**
     * 生成经销商客户编码
     *
     * @param
     * @return 结果
     */
    @Override
    public ServiceResponse generateCustAccCode() {
        String accCodeKey = "cust:" + "account_code_no_key" ;
        Integer accCode = (Integer) redisTemplate.opsForValue().get(accCodeKey);
        if (null == accCode)
        {
            List<String> accCodes = tnMdCustBaseMapper.selectTnMdCustBaseList(null).stream().map(TnMdCustBase::getAcctCode).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(accCodes)){
                List<Integer> codeList = new ArrayList<>();
                accCodes.forEach(e -> codeList.add(Integer.parseInt(e)));
                Integer lastAccCode = codeList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0);
                redisTemplate.opsForValue().set(accCodeKey, lastAccCode);
            }
        }
        accCode = Math.toIntExact(redisTemplate.opsForValue().increment(accCodeKey, 1));
        // 校验
        Integer finalAccCode = accCode;
        if (!CollectionUtils.isEmpty(tnMdCustBaseMapper.selectTnMdCustBaseList(new TnMdCustBase(){{ setAcctCode(finalAccCode.toString());}}))){
            return ServiceResponse.fail("生成失败,客户编码已存在!");
        }
        return ServiceResponse.success(finalAccCode);
    }




推荐:
高并发redis自增increment使用

生成编码时处理并发+事务实际场景

提交工作单时,生成编码,保存提交数据

    /**
     * 提交工作任务单
     *
     * @param custWorkTaskInfoPO
     * @return
     */
    public ServiceResponse submitCTDJCustWorkInfo(CustWorkTaskInfoPO custWorkTaskInfoPO);
    
    /**
     * 保存任务单详情
     *
     * @param custWorkTaskInfoPO
     * @return 结果
     */
    public ServiceResponse saveCTDJCustWorkInfo(CustWorkTaskInfoPO custWorkTaskInfoPO);
    
    /**
     * 处理工作任务单
     *
     * @param tnWorkTask
     * @return 结果
     */
    public ServiceResponse  handleCustCTDJWorkTask(TnWorkTask tnWorkTask) throws Exception;

    /**
     * 处理任务单详情
     *
     * @param custWorkTaskInfoPO
     * @return 结果
     */
    public int handleCTDJCustWorkInfoDetail(CustWorkTaskInfoPO custWorkTaskInfoPO);

    /**
     * 生成经销商任务单号
     *
     * @param custTaskType 经销商任务单类型
     * @return 结果
     */
    public ServiceResponse generateCustTaskIdByTaskType(String custTaskType);



    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResponse submitCTDJCustWorkInfo(CustWorkTaskInfoPO custWorkTaskInfoPO){
        ServiceResponse serviceResponse;
        try {
            serviceResponse = saveCTDJCustWorkInfo(custWorkTaskInfoPO);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("经销商-客户冻结-提交时保存异常", e);
            throw new RuntimeException(e);
        }
        if (serviceResponse.ok()){
            String taskId = custWorkTaskInfoPO.getTnWorkTask().getTaskId();
            try {
                // 提交oa
                return ServiceResponse.success("经销商-客户冻结-提交OA成功" + taskId);
            } catch (Exception e) {
                e.printStackTrace();
                log.warn("经销商-客户冻结-提交OA时异常", e);
                throw new RuntimeException(e);
            }
        }
        return serviceResponse;
    }




    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResponse saveCTDJCustWorkInfo(CustWorkTaskInfoPO custWorkTaskInfoPO) {
        ServiceResponse workTaskResponse = handleCustCTDJWorkTask(custWorkTaskInfoPO.getTnWorkTask());
        if (workTaskResponse.ok()){
            if (handleCTDJCustWorkInfoDetail(custWorkTaskInfoPO) == custWorkTaskInfoPO.getTnMdCustTempBusiScopes().size()){
                return ServiceResponse.success(custWorkTaskInfoPO.getTnWorkTask().getTaskId());
            }
        }
        return workTaskResponse;
    }





    @Override
    public ServiceResponse handleCustCTDJWorkTask(TnWorkTask tnWorkTask) {
        try {
            redisLock.lock("CTDJ");
            String user = SecurityUtils.getLoginUser().getUsername();
            Date now = DateUtils.getNowDate();
            if (StringUtils.isEmpty(tnWorkTask.getTaskId())){
                ServiceResponse response = generateCustTaskIdByTaskType(WorkTaskType.客户冻结.value());
                if (response.ok()){
                    tnWorkTask.setTaskId((String) response.getData());
                }else {
                    return response;
                }
                tnWorkTask.setTaskType(WorkTaskType.客户冻结.value());
                tnWorkTask.setApplicantId(user);
                tnWorkTask.setApplyTime(now);
                tnWorkTask.setCreateBy(user);
                tnWorkTask.setCreateTime(now);
                log.info("经销商-客户冻结-新增任务单{}",tnWorkTask);
                return ServiceResponse.success(tnWorkTaskMapper.insertTnWorkTask(tnWorkTask));
            }else {
                tnWorkTask.setUpdateBy(user);
                tnWorkTask.setUpdateTime(now);
                log.info("经销商-客户冻结-更新任务单{}",tnWorkTask);
                return ServiceResponse.success(tnWorkTaskMapper.updateTnWorkTask(tnWorkTask));
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("经销商-客户冻结-处理任务单异常", e);
        } finally {
            redisLock.unlock("CTDJ");
        }
        return ServiceResponse.fail("经销商-客户冻结-处理任务单失败");
    }




    @Override
    @Transactional(rollbackFor = Exception.class)
    public int handleCTDJCustWorkInfoDetail(CustWorkTaskInfoPO custWorkTaskInfoPO){
        try {
            int affectRows = 0;
            Date now = DateUtils.getNowDate();
            String user = SecurityUtils.getLoginUser().getUsername();
            String taskId = custWorkTaskInfoPO.getTnWorkTask().getTaskId();
            custWorkTaskInfoPO.getTnMdCustTempBusiScopes().forEach(e -> {
                e.setApplyNo(taskId);
                e.setApplyType(WorkTaskType.客户冻结.value());
                e.setStatus(CustDataStatusInteger.NORMAL.value());  //记录状态:10正常 5作废
                e.setCreateBy(user);
                e.setCreateTime(now);
            });
            if (!CollectionUtils.isEmpty(custWorkTaskInfoPO.getTnMdCustTempBusiScopes())){
                for (TnMdCustTempBusiScope tnMdCustTempBusiScope : custWorkTaskInfoPO.getTnMdCustTempBusiScopes()) {
                    affectRows += tnMdCustTempBusiScopeMapper.insertTnMdCustTempBusiScope(tnMdCustTempBusiScope);
                }
            }
            return affectRows;
        }catch (Exception e){
            e.printStackTrace();
            log.error("处理任务单行信息异常", e);
            throw new RuntimeException(e);
        }
    }


    /**
     * 生成经销商任务单号
     *
     * @param custTaskType 经销商任务单类型
     * @return 结果
     */
    @Override
    public ServiceResponse generateCustTaskIdByTaskType(String custTaskType) {
        if (StringUtils.isEmpty(custTaskType)){
            return ServiceResponse.fail("经销商-传入空任务单类型");
        }
        if (!checkIsCustWorkTaskType(custTaskType)){
            return ServiceResponse.fail("经销商-传入任务单类型异常");
        }
        String custTaskId;
        try {
            String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String prefix = custTaskType.toUpperCase() + today ;
            String maxTaskId = tnWorkTaskMapper.selectTodayMaxWorkTaskId(prefix);
            custTaskId = StringUtils.isEmpty(maxTaskId) ? prefix + String.format("%04d", 1) : prefix + String.format("%04d", Long.parseLong(maxTaskId.substring(12)) + 1L);
        }catch (Exception e){
            e.printStackTrace();
            return  ServiceResponse.fail("经销商-任务单号生成异常");
        }
        return ServiceResponse.success(custTaskId);
    }

    private boolean checkIsCustWorkTaskType(String taskType) {
        if (taskType.toUpperCase().equals(WorkTaskType.客户上市.value())
                || taskType.toUpperCase().equals(WorkTaskType.客户基础信息变更.value())
                || taskType.toUpperCase().equals(WorkTaskType.客户更名.value())
                || taskType.toUpperCase().equals(WorkTaskType.客户扩充.value())
                || taskType.toUpperCase().equals(WorkTaskType.客户冻结.value())
                || taskType.toUpperCase().equals(WorkTaskType.客户解冻.value())
                || taskType.toUpperCase().equals(WorkTaskType.基地对外客户上市.value())){
            return true;
        }
        return false;
    }


查询今天任务单类型对应的编码号

    /**
     * 查询申请工作单列表最大的任务单号
     *
     * @param prefix 当天任务单前缀
     * @return 申请工作单集合
     */
    public String  selectTodayMaxWorkTaskId(@Param(value = "prefix") String prefix);

    <select id="selectTodayMaxWorkTaskId" parameterType="String" resultType="java.lang.String">
        SELECT max(task_id) from tn_work_task where task_id like concat( #{prefix}, '%')
    </select>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

宋大米Pro

感谢小主大赏,留言可进互助群~

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

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

打赏作者

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

抵扣说明:

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

余额充值