【获取唯一编号】

在仓库管理系统中,面临各种编号(如货件、入库、出库等)的唯一性需求,不能使用雪花算法和uuid。作者分享了一种利用数据库排他锁实现编号生成的方法,避免使用Java锁和分布式锁,保证了在小规模并发情况下的效率和唯一性。代码示例展示了如何通过事务和数据库锁获取唯一的8位日期+4位随机数编号,同时指出此方案不适用于高并发场景,且未来可根据需求扩展随机数位数。
摘要由CSDN通过智能技术生成

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

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

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

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

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

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

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

最后只能是采用数据库锁来实现这个功能。采用数据库中的排他锁来实现该功能。
首先在数据库中建立一张编号的表
在这里插入图片描述
然后采用往数据库中插入数据的方式,插入成功返回插入的数据。而且由于采用的数据库的锁,也会保障序号的唯一性。

代码放在下面:

   /**
     * 获取单号
     * <p>
     * 利用数据库的排它锁获取唯一的单号
     * </p>
     */
    @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("%05d",no.getNo());
    }

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

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

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

jQuery本身并没有提供获取设备唯一编号的方法,但是可以通过一些第三方库和浏览器API实现。以下是几种常用的方法: 1. 使用Fingerprint.js库获取设备指纹 Fingerprint.js是一个开源的库,可以通过收集浏览器特征来生成一个唯一的设备指纹。可以通过以下代码引入该库并获取设备指纹: ``` <script src="https://cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/2.1.0/fingerprint2.min.js"></script> <script> new Fingerprint2().get(function(result){ console.log(result); // 输出设备指纹 }); </script> ``` 2. 使用Web API获取设备ID 浏览器提供了一些API可以获取设备ID,如DeviceMotionEvent、DeviceOrientationEvent和MediaDevices等。可以通过以下代码获取设备ID: ``` if (typeof devicePixelRatio !== 'undefined') { console.log(devicePixelRatio); // 输出设备ID } ``` 3. 自己生成设备ID 如果以上方法无法满足需求,可以自己生成一个唯一的设备ID。可以通过一些浏览器API和用户信息生成一个唯一的字符串,如以下代码: ``` var uniqueId = ''; if (typeof navigator !== 'undefined') { uniqueId += navigator.userAgent || ''; uniqueId += navigator.plugins.length || ''; uniqueId += navigator.mimeTypes.length || ''; } if (typeof screen !== 'undefined') { uniqueId += screen.width || ''; uniqueId += screen.height || ''; uniqueId += screen.availWidth || ''; uniqueId += screen.availHeight || ''; uniqueId += screen.colorDepth || ''; uniqueId += screen.pixelDepth || ''; } if (typeof window !== 'undefined' && typeof window.location !== 'undefined') { uniqueId += window.location.href || ''; uniqueId += window.location.hostname || ''; uniqueId += window.location.pathname || ''; } console.log(uniqueId); // 输出设备ID ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值