This is the 8th day of my participation in the First Challenge 2022. For details: First Challenge 2022.

An overview of the

Cache consistency is one of the classic problems in using cache. The use of cache involves the maintenance of database and cache data. Since it is the data of two components, there must be data consistency problem. There are three common solutions, which are to set the expiration time, update the database first, then delete the cache, delete the cache first, and then update the database. ?

Setting expiration Time

Code sample

1. Query data

@RequestMapping("/cache/db/{userId}")
@GetMapping
public User getUser(@PathVariable Integer userId){

    // Query the cache
    String str = stringRedisTemplate.opsForValue().get("user:"+userId);

    if(str==null) {// Query the database
        User user = userMapper.selectById(userId);
        // Set the cache
        stringRedisTemplate.opsForValue().set("user:"+userId,JSONUtil.toJsonStr(user),Duration.ofSeconds(100L));
        return user;
    }else {
        returnJSONUtil.toBean(str,User.class); }}Copy the code

2. Update data

@RequestMapping("/cache/db")
@PutMapping
public String update(@RequestBody User user){
    // Update data and wait for the cache to expire to query the real data
    userMapper.updateById(user);
    return "success";
}
Copy the code

The advantages and disadvantages

Advantages: simple and practical coding, low code complexity, can achieve cache and database consistency. Disadvantages: Poor timeliness, you have to wait for the cache to expire before you can see the real data, suitable for scenarios where data is not required in real time.

Update the database before deleting the cache (recommended)

Code sample

@requestMapping ("/cache/db/delete") @putMapping public String updateDelete(@requestBody User User){ Usermapper.updatebyid (user) Query real data after the cache expires. / / delete the cache stringRedisTemplate. Delete (" user: "+ user. GetId ()); return "success"; }Copy the code

The advantages and disadvantages

Advantages: simple and practical coding, low code complexity, can achieve cache consistency, and high real-time.

Disadvantages: 1. High real-time performance, but still not strong consistency, there may be old data before deleting cache

2. If network jitter and cache deletion fails, the real-time performance is not high as in Scheme 1, but some compensation measures can be performed.

Delete the cache first, then update the database

Code sample

@RequestMapping("/cache/db/double/delay/delete")
@PutMapping
public String updateDoubleDelayDelete(@RequestBody User user){
    // Delete the first time
    stringRedisTemplate.delete("user:"+user.getId());
    // Update data and wait for the cache to expire to query the real data
    userMapper.updateById(user);
    // The cache is delayed for the second time
    executorService.submit(()->{
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        stringRedisTemplate.delete("user:"+user.getId()); 
    });
    return "success";
}
Copy the code

The advantages and disadvantages

Advantages: 1. Can achieve cache consistency, also do cache deletion, real-time is also high

2. The first step of the code is to delete the cache. If no thread queries the data at this time and does not query until the database is updated, other query threads will be triggered to query the database and get the latest data, which has a higher real-time performance (compared with scheme 2).

Disadvantages: 1. High code complexity, the use of asynchronous delay secondary delete cache

2. The first step of the code is to delete the cache, if there is another thread query, then the deletion of the cache is not meaningful, the cache is still filled with old data, and wait for the delay of double deletion, but also need a delay time to see the new data

3. If network jitter or cache delay deletion fails, the real-time performance is not high as in Scheme 1, but some compensation measures can be performed

conclusion

1. All three schemes are final consistency

2. The real time performance of scheme 1 is poor, and scheme 2 and Scheme 3 are almost the same. However, I recommend scheme 2 because the code complexity of scheme 2 is low and the cache deletion before scheme deletion still cannot achieve strong consistency, so I recommend scheme 2 to be simpler

3. If strong consistency is really needed, then recommend plus transactions, which will satisfy complete strong consistency unless the business requires very high consistency.