redis踩坑系列之increment

最近寫業務的時候,有個地方需要用到redis的計數器。於是用了increment:

template。opsForValue()。increment(key, delta);但是使用的時候居然報錯:

redis踩坑系列之increment

乍一看以為是自己傳的引數型別有問題,但是明顯不是。於是百度了一下,大部分結果和解決是這樣的:

redis踩坑系列之increment

第一感覺這個解決方案就不太靠譜:

第一,剛接觸這個專案,而且是個老專案,對於這些公共的序列化方式,千萬不能改動。假如改動了,也許會解決你這邊的問題,但是很可能會造成之前的key-value讀取異常,因為之前儲存的是按照另外一種序列化方式儲存的;

第二,全域性搜了一下,專案其他地方也有用到incr方法,所以很可能還是自己使用這邊出了問題。於是重新審閱了一下程式碼,終於發現了原因:

每次初始化的時候,我都使用了這種初始化方式:RedisUtil.set("test", 0); 之所以這麼寫,是因為怕incrment如果是一個不存在的key的時候會拋異常(實際上不會有這種問題,jedis早已處理好了)。但是為什麼加了set方法,就會報錯呢?結合上面搜尋的結果,分析出了原因:開始使用set方法,RedisTemplate會使用預設的序列化方式儲存value,也就是StringRedisSerializer。當走到RedisUtil.incr("test", 1)的時候,redisTemplate會預設把原有key當成long的初始型別+1,所以這個時候就報錯了:java.lang.Integer cannot be cast to java.lang.String

所以解決方式也很簡單,初始化的時候不要set(“test”, 0),直接del(“test”)就行。如果redis是個人獨立使用並且是新模組,可以設定序列化為:FastJsonRedisSerializer。這樣即便是在incr之前set,也不會有任何問題。