从Spring中的异步函数调用时缓存不刷新

时间:2017-08-29 11:44:28

标签: caching asynchronous spring-boot ehcache spring-cache

我正在调用一个有CacheEvict注释的函数。这是从一个本身异步执行的函数调用的。

执行该功能后似乎没有驱逐缓存。

以下是示例代码

@Async("executor1")
public void function1()
{
    // do something

    anotherFunction("name", 123, 12);

   // do something more

}

@CacheEvict(cacheNames = {"cache1", "cache2", "cache3"}, key = "#testId")
public List<Integer> anotherFunction(String name, int testId, int packageId)
{
  // some code here
}

我想要的是应该从所有缓存中清除对应于testId的条目。 但是,在另一个电话中,我可以看到cache1的旧条目。正在从控制器调用function1。这两个功能都存在于服务中。现在,这个配置是否正确?如果是,那么缓存未被清除的可能原因是什么?

任何帮助表示赞赏。提前谢谢。

1 个答案:

答案 0 :(得分:1)

我认为你的问题是Spring代理不是可重入的。为了实现AsyncCacheEvict,Spring创建了一个代理。因此,在您的示例中,调用堆栈将是:

A -> B$$proxy.function1() -> B.function1() -> B.anotherFunction()

B$$proxy包含异步和驱逐的逻辑。直接调用anotherFunction时不适用。实际上,即使您删除了@Async,它仍然无效。

您可以使用的技巧是将代理bean注入到类中。要改为委托代理this

public class MyClass {    
  private MyClass meWithAProxy;

  @Autowired
  ApplicationContext applicationContext;

  @PostConstruct
  public void init() {
    meWithAProxy = applicationContext.getBean(MyClass.class);
  }

  @Async("executor1")
  public void function1() {
    meWithAProxy.anotherFunction("name", 123, 12);
  }

  @CacheEvict(cacheNames = "cache1", key = "#testId")
  public List<Integer> anotherFunction(String name, int testId, int packageId) {
    return Collections.emptyList();
  }

}

有效。但是有一个问题。如果您现在直接致电anotherFunction,则无法使用。我认为这是一个Spring bug,并将按原样提交。