栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【获取唯一编号】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【获取唯一编号】

最近遇到一个问题在这里和大家分享一下:
目前在做仓库管理系统,在系统中遇到了很多的编号问题。如货件编号,入库编号,出库编号,清点编号,发货编号等等。这些编号都是按照相似的规则生成的,如货件编号就是"HJ"+8位日期数+4位随机数,入库编号就是“RK”+8位日期数+4位随机数。都是这样的规律。并且要求要具有唯一性。

在这样的情况下,雪花算法和uuid之类之前比较常用一些方法都无法使用了。

最开始想到的是利用加锁在实现:

//伪代码
加锁{
 //1.获取日期
 //2.获取随机数
 //3.循环判随机数在数据库中是否重复,直到选择出一个不重复的数据
 //4.添加编号到数据库
}

这种方式不需要别人来说,缺点就是非常的明显:效率低,不是个好的选择。

而且利用java中的锁,在分布式项目中就失效了。项目经理也在最开始的时候就说过,不推荐使用java中的锁。

所以现在的选在就只能是不使用java中已有的锁来提高上面代码的执行效率。而且分布式的锁在项目中一直没有使用,单独为了一个编号引入分布式锁有点小题大做了。

最后只能是采用数据库锁来实现这个功能。采用数据库中的排他锁来实现该功能。
首先在数据库中建立一张编号的表

然后采用往数据库中插入数据的方式,插入成功返回插入的数据。而且由于采用的数据库的锁,也会保障序号的唯一性。

代码放在下面:

   
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public String getNo() {
        Integer day = Integer.valueOf(LocalDate.now().format(formatter));
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(No::getDay, day);
        queryWrapper.lambda().last("for update");
        List list = noService.list(queryWrapper);

        No no = new No();
        no.setDay(day);
        no.setNo(list == null ? 1 : list.size() + 1);
        noService.save(no);
        return no.getDay() + "" + String.format("%05d",no.getNo());
    }

这里事务的传递采用了REQUIRES_NEW策略,为了保障整个代码执行完成之后立刻提交事务,降低数据库锁,锁住的时间。

这里的问题说一下:8位日期数+4位随机数的这种方式,4位随机数一般来说是肯定不够使用的(这事项目经理的问题),但是项目目前还处于研发阶段,4位随机数完全够用,不够用时在扩充随机数的位数就好了。

还有一点想说的就是,数据库锁这种方式肯定不能在一些并发数高的项目中使用,我们这里目前只是小公司,这样使用是完全没有问题的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/878537.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号