【问题标题】:Spring @Cachable updating dataSpring @Cachable 更新数据
【发布时间】:2013-04-20 13:35:53
【问题描述】:

示例来自:SpringSource

@Cacheable(value = "vets")
public Collection<Vet> findVets() throws DataAccessException {
    return vetRepository.findAll();
}

findVets() 是如何工作的?

第一次,它从vetRepository 获取数据并将结果保存在缓存中。但是如果在数据库中插入一个新的兽医会发生什么 - 缓存是否更新(开箱即用的行为)?如果没有,我们可以配置它来更新吗?


编辑:

但是如果从外部源(例如使用相同数据库的应用程序)更新数据库会发生什么?

【问题讨论】:

    标签: java database spring caching


    【解决方案1】:
    @CachePut("vets")    
    public void save(Vet vet) {..}
    

    你必须告诉缓存一个对象是陈旧的。如果数据更改而不使用您的服务方法,那么您当然会遇到问题。但是,您可以使用

    清除整个缓存
    @CacheEvict(value = "vets", allEntries = true)    
    public void clearCache() {..}
    

    不过,这取决于缓存提供程序。如果另一个应用在没有通知您的应用的情况下更新了数据库,但它使用了相同的缓存,那么另一个应用可能也会更新缓存。

    【讨论】:

    • 他们可以共享同一个缓存提供者吗?
    • 理论上:是的。但是缓存必须作为单独的应用程序运行。 Spring 默认提供者只是一个简单的映射。
    • 当我在 save/update 方法上使用@CacheEvict 并在 findAll 上使用@Cacheable 时,它可以正常工作。当我尝试@CachePut 时,总是会导致调用该方法并将其结果存储在关联的缓存中,在保存/更新时不会返回更新的记录。你能分享一下你的想法吗
    • 为什么这是公认的答案?问题不是更新数据而不是如何清除它,以便在再次调用方法时填充它。恕我直言
    【解决方案2】:

    它不会自动完成,缓存也无法知道数据是否被外部引入。

    检查@CacheEvict,这将帮助您在底层集合发生任何更改时使缓存条目无效。

    @CacheEvict(value = "vet", allEntries = true)
    public void saveVet() {
      // Intentionally blank
    }
    

    所有条目
    是否删除缓存中的所有条目。
    默认情况下,仅删除关联键下的值。请注意,不允许将此参数设置为 true 并指定键。

    【讨论】:

      【解决方案3】:

      您也可以在创建新条目的方法上使用@CachePut。返回类型必须与 @Cachable 方法中的相同。

      @CachePut(value = "vets")
      public Collection<Vet> updateVets() throws DataAccessException {
          return vetRepository.findAll();
      }
      

      在我看来,外部服务必须调用相同的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-17
        • 2017-02-05
        • 2018-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多