首页 >> 大全

【获取唯一编号】

2023-08-06 大全 25 作者:考证青年

最近遇到一个问题在这里和大家分享一下:

目前在做仓库管理系统,在系统中遇到了很多的编号问题。如货件编号,入库编号,出库编号,清点编号,发货编号等等。这些编号都是按照相似的规则生成的,如货件编号就是"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<No> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().eq(No::getDay, day);queryWrapper.lambda().last("for update");List<No> 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("d",no.getNo());}

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

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

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

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了