0

我正在尝试使用 Hibernate Reactive Panache 将我的项目迁移到 Quarkus Reactive,但我不确定如何处理缓存。

我原来的方法是这样的

    @Transactional
    @CacheResult(cacheName = "subject-cache")
    public Subject getSubject(@CacheKey String subjectId) throws Exception {
        return subjectRepository.findByIdentifier(subjectId);
    }

如果可用,则通过缓存键“subjectId”从缓存中加载主题。

迁移到 Mutiny 看起来像这样

    @CacheResult(cacheName = "subject-cache")
    public Uni<Subject> getSubject(@CacheKey String subjectId) {
        return subjectRepository.findByIdentifier(subjectId);
    }

但是,将 Uni 对象存储在缓存中是不对的。

也可以选择将缓存作为 bean 注入,但是,回退函数不支持返回 Uni:

    @Inject
    @CacheName("subject-cache")
    Cache cache;


  //does not work, cache.get function requires return type Subject, not Uni<Subject>
  public Uni<Subject> getSubject(String subjectId) {
        return cache.get(subjectId, s -> subjectRepository.findByIdentifier(subjectId));
    }

  //This works, needs blocking call to repo, to return response wrapped in new Uni
  public Uni<Subject> getSubject(String subjectId) {
        return cache.get(subjectId, s -> subjectRepository.findByIdentifier(subjectId).await().indefinitely());
    }

@CacheResult 注释可以与 Uni / Multi 一起使用并且一切都在引擎盖下正确处理吗?

4

2 回答 2

1

您的带有@CacheResult返回方法的示例Uni应该实际上可以工作。该实现将自动“剥离”Uni类型并仅将其存储Subject在缓存中。

于 2022-01-28T07:57:56.853 回答
0

缓存 Unis 的问题在于,根据这个 Uni 的创建方式,多个订阅可以多次触发某些代码。为避免这种情况,您必须像这样记住 Uni:

@CacheResult(cacheName = "subject-cache")
public Uni<Subject> getSubject(@CacheKey String subjectId) {
    return subjectRepository.findByIdentifier(subjectId)
        .memoize().indefinitely();
}

这将确保每次订阅缓存的 Uni 将始终返回相同的值(项目或失败),而无需重新执行原始 Uni 流的任何内容。

于 2022-01-28T19:57:22.280 回答