建一个订单对象

/*** 订单号 对象*/
@Data
public class OrderNumberVo implements Serializable {/*** 日期字符串 格式:"yyyyMMdd"*/private String meetDate;/*** 计数id*/private Integer id;/*** 订单号 格式:"yyyyMMddXXX1"*/private String orderNumber;}

业务接口中定义缓存名称

public interface IReserveOrderService extends IService<ReserveOrder> {public static String CACHE_ORDERNUMBER="ordernumber_cache";String createOrderNumber();
}

业务类中实现创建订单号方法

@Service
@Slf4j
public class ReserveOrderServiceImpl extends ServiceImpl<ReserveOrderMapper, ReserveOrder> implements IReserveOrderService {@ResourceRedisUtil redisUtil;private static AtomicInteger atomicInteger=new AtomicInteger();/*** 生成订单号** @return*/@Overridepublic String createOrderNumber() {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");String format = dateFormat.format(new Date());Integer id = 0;String orderNumber = "";while (true) {OrderNumberVo vo = this.getCache();if (vo == null) {//此时没有缓存,从数据库中读取当天的订单ReserveOrder order = this.getOne(new LambdaQueryWrapper<ReserveOrder>().likeRight(ReserveOrder::getOrderNumber, format).last("limit 1"));if (order != null) {id = Integer.valueOf(order.getOrderNumber().substring(format.length()));}vo = new OrderNumberVo();} else {id = vo.getId();}if(atomicInteger.get()==0) {atomicInteger.set(id++);}orderNumber = String.format("%s%04d", format, atomicInteger.incrementAndGet());vo.setMeetDate(format);vo.setOrderNumber(orderNumber);OrderNumberVo cache = this.getCache();if (cache==null || ( cache!=null && cache.getId() == vo.getId())) {//如果缓存中的id 和 前边获取到的vo对象中id一致,就更新缓存,中断循环vo.setId(atomicInteger.get());//更新idthis.setCache(vo);break;}}return orderNumber;}private OrderNumberVo getCache() {OrderNumberVo vo = (OrderNumberVo) redisUtil.get(IReserveOrderService.CACHE_ORDERNUMBER);return vo;}private void setCache(OrderNumberVo vo) {redisUtil.set(IReserveOrderService.CACHE_ORDERNUMBER, vo);}
}

单元测试

    @Testpublic void testOrderNumber(){for(int i=0;i<20;i++){new Thread(()->{String orderNumber = orderService.createOrderNumber();log.info("订单号 = {}",orderNumber);}).start();}}

说明:在redis中保存业务订单对象,每次需要创建业务号时,先获取这个对象,在这个对象中使用原子操作AtomicInteger 生成新的业务号,写入缓存时,判断这个对象与缓存中保存的订单对象id是否一致,不一致时说明已经有另外的操作在生成业务号期间写入了新的业务号,这个时候需要再次重复操作,直到能正确写入缓存为止,表示生成的业务号是唯一的。

经几轮单元测试,每次都能正确生成不重复的业务号,暂时假定这个方法是正确的,还有待实际业务检验。数据表中要将业务号字段设置成唯一约束,避免万一情况。

使用redis 加锁的方式生成订单号相关推荐

  1. redis生成订单号案例

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.redis的相关工具类 二.生成订单号相关方法 前言 项目开发中遇到了对订单号的修改,这里只是实现了利用redis ...

  2. java 订单号 交易锁_(精)订单加锁及生成订单号

    今天看了黎活明老师的 实现订单加锁解锁(也包括生成订单号)功能 的视频,即多人操作(审核等)订单时的如何加锁. 对事务并发又温习了一下.涉及的东西无非是操作系统的多线程引起的并发,这里有个概念就是cp ...

  3. php根据当天日期生成编号,前台js根据当前时间生成订单号

    *********前台显示框**************** **************js代码***************** function GetDateNow() { var vNow ...

  4. php如何生成订单号,php如何生成不重复订单号

    php生成不重复订单号的方法:首先可以预先生成订单号:然后进行去重存起来:最后用的时候取一个出来用就行,代码为[$orderNo = date('YmdHis').substr(microtime() ...

  5. php 快递单号生成规则,Thinkphp 生成订单号小案例

    Thinkphp 生成订单号小案例小伙伴们在日常的商城项目开发中,都会遇到订单号生成的问题,今天呢思梦PHP就带领大家去解读一下生成订单号的问题!首先,订单号我们要明确它有有3个性质:1.唯一性 2. ...

  6. Java 有序生成订单号或流水号

    前言   最近用到了一些编号的生成规则记录一下,有序的生成订单号或者流水号 概述   第一种方式,适用于循环生成订单编号,例如有 100 条数据,需要循环生成相对应编号可以使用,下方的方法,仅限于特定 ...

  7. python生成订单号或生成任意序列

    python生成订单号或生成任意序列 示例代码: import time# 生成订单号 def get_order_code():# 年月日时分秒+time.time()的后7位order_no = ...

  8. PHP制作订货,PHP生成订单号的两种方法

    在开发项目的时候经常有生成订单号的需求,这里列出两种生成20位订单号的常用方法. 方法一: 以下代码是14位当前时间加6位随机数,如果增减位数,只需修改末尾的数字6即可.<?php Functi ...

  9. php订单号递增,PHP生成订单号的两种方法

    在开发项目的时候经常有生成订单号的需求,这里列出两种生成20位订单号的常用方法. 方法一: 以下代码是14位当前时间加6位随机数,如果增减位数,只需修改末尾的数字6即可.<?php functi ...

最新文章

  1. Pytorch 深度学习实战:视频自动打码
  2. 华为服务器bios配置性能,高级电源管理配置 - 华为服务器 Brickland平台 BIOS 参数参考 30 - 华为...
  3. 把骆驼命名法的变量,变为大写字母变小写且之前加下划线
  4. 携程Apollo分布式配置中心搭建指南
  5. 大数据之_数据采集Flume_Flume了解_学习内容介绍---Flume工作笔记002
  6. c+mysql+sslmode_MySQL配置SSL主从复制
  7. svg 贝塞尔曲线图解(记录)
  8. 在vscode中使用ajax,vscode中的ajax片段,
  9. TranslateMessage 和 DispatchMessage
  10. 用 Vue 做一个简单的购物app
  11. 陈纪修老师《数学分析》 第06章:不定积分 笔记
  12. 如何使用ArcMap将Excel数据转换为shp数据
  13. sqlmap安装历程
  14. 软件研发软件基础设施的建设
  15. 2020switch电信最快的dns_《2020switch电信最快的dns》电影_2020switch电信最快的dns正片免费观看-扬州人才服务网...
  16. 软件的界面测试是什么?怎么设计的?
  17. c语言容斥原理求素数,容斥定理相关题目讲解
  18. 把Android API文档的颜色改成不易疲劳的绿豆沙颜色
  19. java后台实现支付宝支付接口、支付宝订单查询接口 前端为APP
  20. php文字加边框,图片加特效文字 图片添加各种边框的文字效果 如果有多种边框模板就更好了...

热门文章

  1. Android9.0 升级webview方法-仅备忘
  2. 【每天学习一点新知识】网络安全--拒绝服务攻击
  3. 从平面设计这一课程中我学到了很多知识
  4. Pandaria - GraphQL API测试
  5. 多益网络校招 -- 主观题
  6. PEP 8 E231 missing whitespace after ‘,’
  7. 正数、负数、和小数正则表达式 ios_iOS开发学习指南(2020)
  8. 十大相似图片搜索网站(以图搜图)
  9. MySQL向SQLite的数据库迁移(SQL文件转存为DB文件)
  10. 一个实时显示系统时钟的android应用