Pitfalls of redisTemplate serialization

Prefix code:

@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate redisTemplate;

    public void set(Object key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public void incr(Object key) {
        redisTemplate.opsForValue().increment(key);
    }
}

Pit 1: By default, JdkSerializationRedisSerializer is used as the serializer. To achieve auto-increment, you can only directly call auto-increment. You cannot set it first and then call auto-increment. The biggest pitfall is that if the set is a java object, the object member attributes will increase. Or when it is reduced, it will cause get to report an error. This will not be demonstrated here , as follows

 

Pit 2: In order to solve the error ERR value is not an integer or out of range, you need to set up a serializer:

@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate redisTemplate;

    @PostConstruct
    public void setRedisSerializer() {
        //key采用string序列化
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(keySerializer);
        redisTemplate.setHashKeySerializer(keySerializer);
        //值采用GenericJackson2JsonRedisSerializer
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
    }

    public void set(Object key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public Object get(Object key) {
        return redisTemplate.opsForValue().get(key);
    }

    public void incr(Object key) {
        redisTemplate.opsForValue().increment(key);
    }
}

But there will be another problem: when the set is a java object and it contains the LocalDateTime type, an error will be reported when reading:

public class User implements Serializable {
    private int age;
    private String name;
    private LocalDateTime birthDay;

    public LocalDateTime getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(LocalDateTime birthDay) {
        this.birthDay = birthDay;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 In order to solve this time problem, continue to change the serializer:

@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate redisTemplate;

    @PostConstruct
    public void setRedisSerializer() {
        //key采用string序列化
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(keySerializer);
        redisTemplate.setHashKeySerializer(keySerializer);
        //值采用GenericJackson2JsonRedisSerializer
        GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
        redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericFastJsonRedisSerializer);
    }

    public void set(Object key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public Object get(Object key) {
        return redisTemplate.opsForValue().get(key);
    }

    public void incr(Object key) {
        redisTemplate.opsForValue().increment(key);
    }
}

Unit test passes:

 Then I backtested the two situations of Pit 1 before, and both of them passed smoothly. I won’t take screenshots here to perfectly solve the pits encountered.

Summary: It is recommended to use GenericFastJsonRedisSerializer as the serializer when serializing redisTemplate. This is included in the fastjson package and requires the introduction of fastjson dependencies:

        <dependency>
            <groupId>com.alibaba.</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>

 ps: If redisTemplate is used in the project to implement distributed locks through lua scripts, GenericFastJsonRedisSerializer also has pitfalls. It is recommended to use FastJsonRedisSerializer to perfectly solve all problems. You can check out another blog:

Pitfalls of using redisTemplate to implement distributed locks through lua script_qq_17805707's blog-CSDN blog

Guess you like

Origin blog.csdn.net/qq_17805707/article/details/132047002