高并发redis自增increment使用
1.前言最近修改了一个bug,类型多个用户同时创建订单,需要从数据库获取最大订单号,然后在此基础上为每个订单加1,且不能重复。因为用户可能同时创建订单,导致订单号重复,所以用redis的自增incr,这个像oarcle序列一样不会重复。2.具体实现springboot启动类中添加如下代码@Beanpublic RedisTemplate<String, Object> redisTem
·
1.前言
最近修改了一个bug,类型多个用户同时创建订单,需要从数据库获取最大订单号,然后在此基础上为每个订单加1,且不能重复。因为用户可能同时创建订单,导致订单号重复,所以用redis的自增incr,这个像oarcle序列一样不会重复。
2.具体实现
- springboot启动类中添加如下代码
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 使用GenericJackson2JsonRedisSerializer替换默认序列化
GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// 设置 Key 和 Value 的序列化规则
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
// 初始化 RedisTemplate 序列化完成
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
- service层加入依赖
@Autowired
RedisTemplate redisTemplate;
- 具体取值方法
public String getMaxID() {
String maxId = "";
try {
synchronized (当前类.class){
Object redisKey = redisTemplate.opsForValue().get("orderId");
if (redisKey == null) {
// 假设此处maxId:"1234"是通过sql查询出来的
maxId = "1234";
if (maxId == "" || maxId == null) {
maxId = "0001";
redisTemplate.opsForValue().increment("orderId", 1);
} else {
Integer order = Integer.parseInt(maxId);
redisTemplate.opsForValue().set("orderId", order);
redisTemplate.opsForValue().increment("orderId", 1);
Integer value = Integer.parseInt(redisTemplate.opsForValue().get("orderId").toString());
// 格式化成4位字符串
maxId= String.format("%04d",value);
}
} else {
redisTemplate.opsForValue().increment("orderId", 1);
Integer value = Integer.parseInt(redisTemplate.opsForValue().get("orderId").toString());
// 格式化成4位字符串
maxId= String.format("%04d",value);
}
}
} catch (Exception e) {
} finally {
redisTemplate.expire("orderId", 60, TimeUnit.SECONDS); // 设置过期时间 60秒
}
return maxId;
}
3.后记
- 这个方法的关键有两点,一是用redis自增,二是锁住当前类,但锁住当前类还有优化空间,应该用双检查锁。
- 可以使用Java的LongAdder或AtomicLong替换redis来实现自增。
点击阅读全文
更多推荐
活动日历
查看更多
直播时间 2025-02-26 16:00:00


直播时间 2025-01-08 16:30:00


直播时间 2024-12-11 16:30:00


直播时间 2024-11-27 16:30:00


直播时间 2024-11-21 16:30:00


目录
所有评论(0)