代码之家  ›  专栏  ›  技术社区  ›  dpr

弹簧@可缓存双重检查锁定(infinispan后端)

  •  0
  • dpr  · 技术社区  · 8 年前

    我最近开始使用Spring的 @Cacheable

    final String key = SomeClass.computeKey(input)
    String cachedValue = mCache.get(key);
    if (cachedValue == null) {
        synchronized (mCache) {
            cachedValue = mCache.get(key);
            if (cachedValue == null) {
                cachedValue = expensiveComputing(input);  // must not be executed twice
                mCache.put(key, cachedValue);
            }
        }
    }
    

    @Cacheable(value="someCache", key="T(SomeClass).computeKey(#input)")
    public String expensiveComputing(Object input) {
        // must not be executed twice
    } 
    

    有时,还有第二个缓存用于缓存锁对象以进行实际查找,以避免在计算缓存值期间在整个缓存上进行大量同步。

    我已经读过了 infinispan's docu on locking 我仍然想知道我是否需要自己处理这些方面,或者英菲尼斯潘是否保证了预期的行为。

    expensiveComputing

    1 回复  |  直到 8 年前
        1
  •  4
  •   jihor    8 年前

    Spring 4.3+和Infinispan 9.0+支持这一点 sync=true 在里面 @Cacheable this Spring ticket this Infinispan ticket )

    长答案

    在Spring 4.3之前,简单地用 o.s.c.a.JCacheCacheAspect o.s.c.j.i.JCacheAspectSupport

    因此,昂贵的计算完全有可能发生两次。在这种情况下,额外的同步取决于程序员。因此,双重检查锁定仍然有用。

    org.infinispan.jcache.annotation.InjectedCacheResultInterceptor ,编写自己的实现 org.infinispan.jcache.annotation.AbstractCacheResultInterceptor ,它将负责锁定。例如,类的实现可能有一些字典来决定 InvocationContext 需要这样的锁定。

    @可缓存 在这种情况下,带来的痛苦大于收获。从事务管理器创建缓存,并使用它对事务进行一些控制,就像在Infinispan中一样 tutorials 似乎更简单、更简洁。

    从春季4.3开始, @可缓存 sync 属性,该属性提示必须同步整个操作。Infinispan从9.0版起就支持这一点。