利用Redis生成业务流水号思路

  • Post author:
  • Post category:其他


系统需要生成根据业务类型生成流水号,每天从1开始生成,第二天会清零继续从0开始,流水号格式为: bizCode + date + incr  如:TT-2017112300001。

思路:利用Redis Incr 生成序列号,使用日期加业务编码作为组合Key,这样保证第二天生成的序列号又是从1开始。

由于我们业务量不是很大,这里在生成序列号之前先判断一下当前key是否存在,若不存在,设置此key过期时间为当天晚上23:59:59,避免生成很多过期的key。

整体设计流程思路如下:

关键代码如下:

@Service
public class SerialNumberServiceImpl implements ISerialNumberService {
    @Autowired
    private JedisCluster jedisCluster;
    /**
     * 定义流水号工单默认前缀
     */
    private static final String SERIAL_NUMBER = "itsm:serial:";
 
    @Override
    public String generate(String bizCode) {
 
        if(StringUtils.isEmpty(bizCode)){
            throw new ServiceException("流水号业务类型不能为空");
        }
 
        //获取当前时间,返回格式如yyyyMMdd
        String date = TimeUtil.date2Str(new Date(), ItsmConstants.FORMATTER_YYYYMMDD_DAY);
 
        //构造redis过期时间 UnixMillis
        //设置过期时间为当前时间的最后一秒
        long expire = TimeUtil.time2UnixMillis(date + " 23:59:59",ItsmConstants.FORMATTER_YYYYMMDD_TIME);
 
        //构造redis的key
        String key = SERIAL_NUMBER + date +":"+ bizCode;
 
        //判断key是否存在
        Boolean exists = jedisCluster.exists(key);
 
        Long incr = jedisCluster.incr(key);
 
        //设置过期时间
        if(!exists){
            jedisCluster.pexpireAt(key,expire);
        }
 
        //默认编码需要5位,位数不够前面补0
        String formattNum = String.format("%05d", incr);
        StringBuilder sb = new StringBuilder(20);
        //转换成业务需要的格式  bizCode + date + incr
        sb.append(bizCode).append("-").append(date).append("-").append(formattNum);
 
        return sb.toString();
    }
}



版权声明:本文为qq_38730338原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。