侧边栏壁纸
博主头像
JavaLYG 博主等级

行动起来,活在当下

  • 累计撰写 32 篇文章
  • 累计创建 8 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

java生成15位流水号保证不重复

liuyg
2024-04-25 / 0 评论 / 0 点赞 / 31 阅读 / 0 字 / 正在检测是否收录...

问题及背景

再项目中需要传入一个支付的流水号,收单机构规定为15位。那么就需要保证这个15位的流水号是永不重复的。

解决方案

  1. 先获取13位时间戳,精确到毫秒级

  2. 获取一个自增长的数字为2位(实际需要字符串才能保证订单号长度固定)(线程同步)❗️❗️❗️

  3. 拼接他俩得到一个毫秒级99次并发不重复的流水号

解决代码

代码:

/**
     * @Author liuyg
     * @Description 同步获取一个顺序号
     * @Date 2024/4/25 9:13
     * @Return java.lang.String
     */
    private static Integer serialNumber = 0;
    private static synchronized String getSerialNumber() {
        serialNumber++;
        if (serialNumber >= 99) {
            serialNumber = 0;
        }
        return java.lang.String.format("%02d", serialNumber);
    }

    /**
     * @Author liuyg
     * @Description 获取订单号
     * @Date 2024/4/25 9:29
     * @Return java.lang.String
     */
    public static String createOrdeNo() {
        String ordeNo = System.currentTimeMillis() + getSerialNumber();
        return ordeNo;
    }

测试代码:

    public static void main(String[] args) {
        long w = 0;
        for (int q = 0; q < 10000; q++) {
            List<String> list = new ArrayList<>();
            for (int i = 0; i < 99; i++) {
                String outTradeNo = createOrdeNo();
                list.add(outTradeNo);
            }
            long numDuplicates = list.stream()
                    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                    .values()
                    .stream()
                    .filter(count -> count > 1)
                    .count();
            w += numDuplicates;
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        System.out.println(w);
    }

测试代码是循环10000轮次,每次生成99个,延迟1毫秒。模拟每毫秒99次并发的场景,不会出现重复流水号的场景,但是就局限于每毫秒99次的并发,超过了此方案必然重复

总结

虽然本方案局限于每毫秒99次的并发,但是目前我们项目这个场景是够用了😀😀😀

主要是通过每毫秒的速度之快,以及每毫秒上面加一个顺序数,保证同一毫秒级别并发的时候出现重复流水号的情况。当然也可以给createOrdeNo方法加synchronized关键字。

0

评论区