java 实现流水号 日期加 序号

文章讲述了如何实现在业务系统中生成流水号,包括一种与业务耦合但不使用Redis的方法,以及利用Redis实现解耦和自动增长的方案。前者可能存在导入失败导致流水号冲突的问题,后者借助Redis的分布式锁确保唯一性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:需要实现生成编号流水号

按照日期 yyyyMMDD 加当天加入的序号

方法一: 与业务耦合 不使用redis 

1.取当天加入的人数 为空 从1开始

存在问题 导入时 有部分失败 但是流水号已作废导致导入10位成员  可能失败3条  最终第7位流水号为2024022100010

再次单独添加时为出现流水号重复

解决: 取当天加入的最大流水号 

private String getCurrentDataString(){
        // 获取当前日期
        Date currentDate = new Date();
        // 创建SimpleDateFormat对象,指定日期格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        // 格式化日期
        return dateFormat.format(currentDate);
    }

//如果获取当天的最大数流水号为空  设置初始值
String codeNumber  = getCurrentDataString+String.format("%05d", 0);

//如果已存在 及累加即可
Long Code = LongUtils.str2Long(codeNumber);

code+(目标数)

方法二.使用redis  与业务解耦合

根据key 去redis中查询  根据redis的自增 进行处理

public List<String> getSerialnumber(String key, Integer length) throws Exception{
        //key 20230306
        //在redis缓存中查找改key.
        //将该key自增1 返回
        String code = "CODENUMBER:";
        Boolean existKey = redisService.isExistKey(code+key);
        if(!existKey){
            //如果查询不到,将数据库的最大值读入缓存。//保证只有一个线程执行初始化键操作
            //加锁
            String redisKey = getClass().getSimpleName() + ":Code:" + key;
            String lockValue = null;
            try{
                lockValue = redisDistributedLock.lock(redisKey, 5000,1000);
                if (StringUtils.isEmpty(lockValue)) {
                    throw new BaseException("稍后重试");
                }
                //最大值
                // 从数据库获取做大值
                int max = 0;
                //todo               
                //再查一次缓存
                String redisValue = redisService.get(code + key);
                if(StringUtils.isEmpty(redisValue)){
                    if(StringUtils.isEmpty(redisValue) || (max >=redisValue))
                    //本地大于缓存 才更新
                    redisService.set(code + key,String.valueOf(max));
                }
            }catch (Exception e){
                e.printStackTrace();
                throw e;
            }finally {
                redisDistributedLock.unlock(redisKey, lockValue);
            }
        }
        List<String> nums = new ArrayList<>();
        Integer no = null;
        for(int i = 0; i < length; i++){
            //redis  自增
            no = IntegerUtils.valueOf(redisService.incrby(code + key, 1L));
            String sNO = key + String.format("%05d", no);
            nums.add(sNO);
        }
        return nums;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值