springboot生成订单号问题
最近在学springboot,有个需求是生成订单号,格式规则如下:yd-20221029-0001
固定前缀-日期-当日单数,隔日从0开始
在学习过程中发现有的网上的做法是写个mapper直接从数据库取当天最大单号+1,然后实体类set后插入数据库。
这样写的话如果多个用户同时创建订单是否可能出现订单号重复问题,这种需求应该挺常见的,但不太清楚如何做比较合理,麻烦各位大佬帮忙看看{:1_932:} public static String createStr(String prefix) {
return prefix + DateUtil.toString(new Date(), "yyyyMMdd") + SnowFlake.getId();
} 解决方法:
第一种: for update 加锁 或者 redis分布式锁 再操作mysql查询、更新 ;
优点:严格递增
缺点 : 数据库存在性能瓶颈
第二种:使用redis incr指令进行原子操作递增,返回新值
优点:严格递增;无需加锁,性能好;可设置过期时间自动对key进行回收
缺点:强依赖redis,宕机容易导致一段时间不可以用。
第三种:号段模式+本地缓存,每次获取一批id进行本地缓存,通过guava cache可设置本地缓存过期时间及时0点清理
优点:趋势递增;业务服务分摊数据存储中间件写并发;弱依赖数据存储中间件,通过本地缓存可在宕机期间提供服务
缺点:安全性不好,容易泄露发号数量的信息
第四种 雪花算法
优点: 趋势递增;本地生成性能好;安全性好,竞争对手无法通过id计算发号数量
缺点:时钟回拨
时间+递增数字+随机数 三楼说得对{:301_998:} 建议是用雪花算法,虽然生成的ID不是你要的这种,但是可解密出日期,最大数量可跟在ID后面,别人也猜不出来 可以看看美团的开源项目leaf,订单号生产策略。 本帖最后由 wangqh761117 于 2022-12-12 09:50 编辑
按你的需求,应该用主键回填就可以了
<insert id="save" useGeneratedKeys="true" keyProperty="id">
...
orderMapper.save(order);
完了之后,再order.getId()就能拿到自增长的id值 siegod 发表于 2022-12-12 04:59
解决方法:
第一种: for update 加锁 或者 redis分布式锁 再操作mysql查询、更新 ;
大佬的方案很全面呀 三楼说的对
页:
[1]
2