【问题标题】:@Cacheput not working for updates only inserts@Cacheput 不适用于更新仅插入
【发布时间】:2018-07-13 07:05:39
【问题描述】:

下面是我的代码 sn-p。 @cacheput 仅在第一次调用时将数据插入到 redis 中。第二次调用保存函数时不更新值。引用的 CacheManager 是一个 RedisCacheManager。

@CachePut(cacheNames = "User", key = "#user.Id")
@Override
public Optional<User> save(User user) {
    if(em.contains(user) || user.isPersisted()) { // merge if exists
        User retVal = em.merge(user);
        retVal.setPersisted(true);
        System.out.println("hashCode after merge-->"+retVal.hashCode());
        return Optional.ofNullable(retVal);
    } else {
        em.persist(user);
        user.setPersisted(true);
        return Optional.ofNullable(user);
    }
}

正在使用的依赖项:

<dependency>
    <groupId>biz.paluch.redis</groupId>
    <artifactId>lettuce</artifactId>
    <version>4.3.2.Final</version>
</dependency>

我确实验证了要更新的对象和第一次保存时插入的对象的哈希码,它们是不同的。

【问题讨论】:

  • 那么else 正在第二次调用中运行?所以em.contains(user)user.isPersisted() 在第二次通话中都是假的? user.equals() 是什么样的?第二次调用的方法是如何调用的?
  • if 块在第二次调用时执行,而 else 块在第一次调用时执行。即使第二次也以相同的方式使用代理调用方法。我可以在第二次保存期间看到缓存的跟踪日志,类似于第一次。 equals 方法将用户的每个属性与对象进行比较并返回 false。我添加了一个记录器来验证 object1.equals(object2) 是否为假,其中第一次保存的 object1 和第二次保存的 object2

标签: java spring caching redis lettuce


【解决方案1】:

我发现了问题。我的保存方法在一个用

注释的 DAO 类中

@Transactional

。尽管 DB 提交正在发生,但在整个全局事务成功提交之前,Redis 提交不会发生。所以我加了

@Transactional(propagation=Propagation.REQUIRES_NEW)

使用@cacheput 方法添加到我所有 Dao 类中的事务注释,这解决了我的问题。考虑到两阶段提交可能面临的问题,我知道将其添加到 DAO 方法中是个坏主意。但在我目前的用例中,这不是问题。

【讨论】:

    猜你喜欢
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多