Spring Cloud Spring Boot mybatis分布式微服务云架构(三十六)使用Redis作集中式缓存(2)

问题思考

为何一样的逻辑在EhCache中没有问题,可是到Redis中会出现这个问题呢?html

在EhCache缓存时没有问题,主要是因为EhCache是进程内的缓存框架,第一次经过select查询出的结果被加入到EhCache缓存中,第二次查询从EhCache取出的对象与第一次查询对象其实是同一个对象(能够在使用Chapter4-4-1工程中,观察u1==u2来看看是不是同一个对象),所以咱们在更新age的时候,实际已经更新了EhCache中的缓存对象。redis

而Redis的缓存独立存在于咱们的Spring应用以外,咱们对数据库中数据作了更新操做以后,没有通知Redis去更新相应的内容,所以咱们取到了缓存中未修改的数据,致使了数据库与缓存中数据的不一致。数据库

所以咱们在使用缓存的时候,要注意缓存的生命周期,利用好上一篇上提到的几个注解来作好缓存的更新、删除缓存

进一步修改

针对上面的问题,咱们只须要在更新age的时候,经过@CachePut来让数据更新操做同步到缓存中,就像下面这样:框架

@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository<User, Long> {

    @Cacheable(key = "#p0")
    User findByName(String name);

    @CachePut(key = "#p0.name")
    User save(User user);

}

在redis-cli中flushdb,清空一下以前的缓存内容,再执行单元测试,能够得到下面的结果:单元测试

Hibernate: insert into user (age, name) values (?, ?)
第一次查询:10
第二次查询:10
Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.name as name3_0_0_ from user user0_ where user0_.id=?
Hibernate: update user set age=?, name=? where id=?
第三次查询:20

能够看到,咱们的第三次查询得到了正确的结果!同时,咱们的第一次查询也不是经过select查询得到的,由于在初始化数据的时候,调用save方法时,就已经将这条数据加入了redis缓存中,所以后续的查询就直接从redis中获取了。测试

本文内容到此为止,主要介绍了为何要使用Redis作缓存,以及如何在Spring Boot中使用Redis作缓存,而且经过一个小问题来帮助你们理解缓存机制,在使用过程当中,必定要注意缓存生命周期的控制,防止数据不一致的状况出现。spa

源码来源code

相关文章
相关标签/搜索