利用redis生成自增编号
/*** redis key的层级不能超过3层()* 根据前缀+日期+每天的自增编号例如(WF2021041411200001)** @param prefix* @param key* @param length* @return*/public String getDayIncrCode(String prefix, String key, int length) {Stri...
·
基本思路
1、利用Redis中RedisAtomicLong类和其方法incrementAndGet()实现自增操作。
2、获取当天剩余的时间转化为秒,设置redis对应key值的失效时间
3、按照编号规则组装数据
遇到的坑
1、编号会存在重复操作,解决方案
(1)在创建RedisAtomicLong类时使用Redisson分布式锁,详见下列代码
(2)、使用下面代码替代RedisAtomicLong操作
Long increment = redisTemplate.opsForValue().increment(key, 1);
redisTemplate.expire(key,liveTime, TimeUnit.SECONDS);
2、Redisson分布式锁创建失败,为null,解决方案需要对redisTemplate进行序列化配置
/**
* redis key的层级不能超过3层()
* 根据前缀+日期+每天的自增编号例如(WF2021041411200001)
*
* @param prefix
* @param key
* @param length
* @return
*/
public String getDayIncrCode(String prefix, String key, int length) {
String code = "";
String formatDay = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
Long dayEndTime = getAppointDateTimeMills();
//当天失效
long liveTime = (dayEndTime - System.currentTimeMillis()) / 1000;
Long incre = getIncre(key, liveTime);
String sequence = getSequence(incre, length);
if (StrUtil.isNotBlank(prefix)) {
code = code + prefix;
}
code = code + formatDay + sequence;
return code;
}
获取当天结束的时间戳
/**
* 获取指定时间毫秒值
*
* @return
*/
public static Long getAppointDateTimeMills() {
Calendar ca = Calendar.getInstance();
//失效的时间
ca.set(Calendar.HOUR_OF_DAY, 23);
ca.set(Calendar.MINUTE, 59);
ca.set(Calendar.SECOND, 59);
long curtime = ca.getTimeInMillis();
return curtime;
}
利用Redis中RedisAtomicLong生成自增(核心使用了 redis中的increment方法)
//RedisAtomicLong源码
public long incrementAndGet() {
return this.operations.increment(this.key, 1L);
}
/**
* 获取redis原子自增数据
*
* @param key
* @param liveTime
* @return
*/
public Long getIncre(String key, long liveTime) {
RedisAtomicLong counter = null;
RLock lock = null;
if (!redisTemplate.hasKey(key)) {
try {
lock = redissonLock.lock(key, 1);
counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
} finally {
redissonLock.unlock(lock);
}
} else {
counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
}
Long increment = counter.incrementAndGet();
//初始设置过期时间
boolean result = (null == increment || increment.longValue() == 0) && liveTime > 0;
if (result) {
counter.set(1);
counter.expire(liveTime, TimeUnit.SECONDS);
increment = 1L;
}
return increment;
}
格式化数据
/**
* 补全自增的数据
*
* @param seq
* @param length
* @return
*/
public static String getSequence(long seq, int length) {
String str = String.valueOf(seq);
int len = str.length();
// 取决于业务规模,应该不会到达4
if (len >= length) {
return str;
}
int rest = length - len;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < rest; i++) {
sb.append('0');
}
sb.append(str);
return sb.toString();
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class IdUtilsTest {
@Autowired
private IdUtils idUtils;
@Test
public void testSequenceCode() {
String key="test:er6666:6666:934";
String formatDay = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
key=key+formatDay;
for (int i = 0; i < 20; i++) {
String st = idUtils.getDayIncrCode("ST", key, 4);
System.out.println(st);
}
}
}
输出结果
更多推荐
已为社区贡献9条内容
所有评论(0)