JAVA 生成不重复订单号 优化版本 订单号格式为yyyymmdd后面自增
博主提供的开源组件 Mybatis-JPA 组件开源地址 https://gitee.com/shuaizai88/jack_mybatis_jpa@Service("orderNumberDubbboServiceImpl")public class OrderNumberDubbboServiceImpl implements OrderNumberDubbboServic
·
博主提供的开源组件 Mybatis-JPA 组件开源地址 https://gitee.com/shuaizai88/jack_mybatis_jpa
@Service("orderNumberDubbboServiceImpl")
public class OrderNumberDubbboServiceImpl implements OrderNumberDubbboService
{
private static Logger LOG = Logger.getLogger(OrderNumberDubbboServiceImpl.class);
private static final Integer ONCE_ORDER_NUM_CREATE =
ConverterUtils.toInt(EConfig.getOtherConfigPropertiesValue("once_order_num_create"), 10);
/**
* redis锁操作service
*/
@Resource(name = "redisLockServiceImpl")
private RedisLockService redisLockService;
@Resource(name = "redisCacheServiceImpl")
private RedisCacheService<Integer> redisCacheService;
/**
* 预先 产生很多订单号 key订单号类型value 预先生产出来的订单号
*/
private Map<String, ConcurrentLinkedQueue<String>> orderNumberQueueMap = new ConcurrentHashMap<>();
public synchronized String getOneOrderNumber(String type)
{
ConcurrentLinkedQueue<String> orderNumbers = null;
orderNumbers = orderNumberQueueMap.get(type);
// 如果有这个类型 并且还有剩余的订单号
if (orderNumberQueueMap.containsKey(type) && (!orderNumbers.isEmpty()))
{
return orderNumbers.poll();
}
initOrderNumber(type);
orderNumbers = orderNumberQueueMap.get(type);
return orderNumbers.poll();
}
/**
* 初始化指定类型的订单号
*
* @param type 类型
*/
private synchronized void initOrderNumber(String type)
{
// 锁表(用于判断现在是否可以创建订单)一小时的超时时间
if (!redisLockService.addRedisLock("REDIS_LOCK_MAX_ORDER_NUMBER", 2000, 2))
{
LOG.infoMsg("获取订单编号失败,订单编码类型为:{}", type);
throw new CheckException(PubResult.SYSTEM_BUSY.asResult());
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
String date = (new SimpleDateFormat("yyyyMMdd")).format(calendar.getTime());
String key = "order_number_" + date + "_" + type;
// key:常量+日期+订单号 value(orderIndex):日期拼接数据
Integer orderIndex = redisCacheService.get(key);
orderIndex = orderIndex == null ? 0 : orderIndex;
int minOrderIndex = orderIndex + 1;
// 每次产生1w个订单号
orderIndex += ONCE_ORDER_NUM_CREATE;
redisCacheService.put(key, orderIndex);
redisLockService.delRedisLock("REDIS_LOCK_MAX_ORDER_NUMBER");
ConcurrentLinkedQueue<String> orderNumbers =
orderNumberQueueMap.containsKey(type) ? orderNumberQueueMap.get(type) : new ConcurrentLinkedQueue<>();
orderNumberQueueMap.put(type, orderNumbers);
for (int i = minOrderIndex; i <= (ONCE_ORDER_NUM_CREATE + minOrderIndex); i++)
{
orderNumbers.offer(StringUtil.formatOrderNumber(date, i));
}
}
思路是 先生成 1w个订单号扔到 队列中,然后 有需要的直接在队列取,如果取不到的话,那么在生成1w个
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)