需求:需要实现生成编号流水号
按照日期 yyyyMMDD 加当天加入的序号
方法一: 与业务耦合 不使用redis
1.取当天加入的人数 为空 从1开始
存在问题 导入时 有部分失败 但是流水号已作废导致导入10位成员 可能失败3条 最终第7位流水号为2024022100010
再次单独添加时为出现流水号重复
解决: 取当天加入的最大流水号
private String getCurrentDataString(){
// 获取当前日期
Date currentDate = new Date();
// 创建SimpleDateFormat对象,指定日期格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
// 格式化日期
return dateFormat.format(currentDate);
}
//如果获取当天的最大数流水号为空 设置初始值
String codeNumber = getCurrentDataString+String.format("%05d", 0);
//如果已存在 及累加即可
Long Code = LongUtils.str2Long(codeNumber);
code+(目标数)
方法二.使用redis 与业务解耦合
根据key 去redis中查询 根据redis的自增 进行处理
public List<String> getSerialnumber(String key, Integer length) throws Exception{
//key 20230306
//在redis缓存中查找改key.
//将该key自增1 返回
String code = "CODENUMBER:";
Boolean existKey = redisService.isExistKey(code+key);
if(!existKey){
//如果查询不到,将数据库的最大值读入缓存。//保证只有一个线程执行初始化键操作
//加锁
String redisKey = getClass().getSimpleName() + ":Code:" + key;
String lockValue = null;
try{
lockValue = redisDistributedLock.lock(redisKey, 5000,1000);
if (StringUtils.isEmpty(lockValue)) {
throw new BaseException("稍后重试");
}
//最大值
// 从数据库获取做大值
int max = 0;
//todo
//再查一次缓存
String redisValue = redisService.get(code + key);
if(StringUtils.isEmpty(redisValue)){
if(StringUtils.isEmpty(redisValue) || (max >=redisValue))
//本地大于缓存 才更新
redisService.set(code + key,String.valueOf(max));
}
}catch (Exception e){
e.printStackTrace();
throw e;
}finally {
redisDistributedLock.unlock(redisKey, lockValue);
}
}
List<String> nums = new ArrayList<>();
Integer no = null;
for(int i = 0; i < length; i++){
//redis 自增
no = IntegerUtils.valueOf(redisService.incrby(code + key, 1L));
String sNO = key + String.format("%05d", no);
nums.add(sNO);
}
return nums;
}