Redis自增incr与过期expire设置过期时间未生效问题
先来看一段代码
redisTemplate.expire(redisKey, 2, TimeUnit.HOURS);
redisTemplate.opsForZSet().incrementScore(redisKey, bookId, 1);
目的在于按小时统计bookId的次数,每次加一,并且设置过去时间为2个小时
如果访问量高一点,这段代码暂时没有问题,但是在灰度测试的时候,这个key的过期时间为-1,即永久生效,
最开始以为incrementScore会覆盖掉前面设置的过期时间,但是这个key是按小时存的,一个小时一个key,结果有的已经过期删除了,有的还是永久生效
最后想了想,发现了问题所在,
首先incrementScore不会覆盖掉之前的过期时间,这段代码第一次执行的时候,
redisTemplate.expire(redisKey, 2, TimeUnit.HOURS);
因为当前这个key是每小时一个,第一次执行时这个key不存在,所以设置过期时间返回结果为0;
如果这个key已经存在,则返回1
redisTemplate.opsForZSet().incrementScore(redisKey, bookId, 1);
设置过期时间失败后执行下面这行代码,booId对应的这个值score加1,没有问题,但是这个时候当前这个key的过期时间为-1永久生效
当第二次执行这段代码的时候,当前这个key已经存在,所以会设过期时间为2个小时,然后继续加score,没有问题,这个时候key的过期时间也生效了
第三次、第四次步入正轨
但是当整段代码只有一次访问时,这个key的过期时间就未生效
查看这个key,会发现里面都只有一条数据
所以调整执行顺序为
redisTemplate.opsForZSet().incrementScore(redisKey, bookId, 1);
redisTemplate.expire(redisKey, 2, TimeUnit.HOURS);