流水号生成、分布式
SpringUtil:获取对象用,其他都在注释里面
public class OrderNoUtil {
/**
* 时间格式化
*/
private final static String DATE_STR = "yyyyMMdd";
/**
* 占位前缀
*/
private final static String PLACE_HOLDER = "00000000000";
/**
* 订单号生成工具类
* @param prefix 前缀
* @param size 流水号位数 最大支持12位,如果不满足需求可以把占位前缀加大
* @param maxValue 如果redis没有做持久化,redis重启,需要传递最大值
* @return
*/
public static String buildOrderNO(String prefix, Integer size, Long maxValue) {
// 获取redis
RedisClient redisClient = SpringUtil.getBean(RedisClient.class);
// 生成前缀 此处为 入参前缀 + 日期 (20230106)
String keyPreFix = prefix + DateUtil.format(new Date(), DATE_STR);
if (maxValue != null){
synchronized (keyPreFix) {
// 设置redis值为传递的最大值,并且过期时间为24小时
Long value = redisClient.get(keyPreFix);
if (value == null || maxValue > value){
redisClient.setEx(keyPreFix, maxValue, Duration.ofHours(24L));
}
}
}else {
if (!redisClient.exists(keyPreFix)){
synchronized (keyPreFix){
if (!redisClient.exists(keyPreFix)){
redisClient.setEx(keyPreFix, 0, Duration.ofHours(24L));
}
}
}
}
// 利用redis自增方法,增加
Long value = redisClient.incr(keyPreFix);
String valueStr = PLACE_HOLDER + value;
return keyPreFix + valueStr.substring(valueStr.length() - size);
}
}
以上仅为个人愚见,如果有更好方案,欢迎大家指出
网友评论