2011-06-15 55 views
1

我试图用spymemcached 2.6与更新同步冲突,我发现以下两种方式来使用它:使用CASMutation定义CASMutator这是相当实施侵入性的方式防止spymemcached

  • 它,让看到一个例子:使用cas方法

    ​​

或通过

cas(String key, long casId, Object value) 

后都做:

gets(String key, Transcoder<T> tc) 

第二个是真的比较简单,我明白为什么我会用CASMutation ... 我会很高兴,以获取有关使用该couchbase的一些反馈客户。

回答

3

CASMutator/CASMutation捕捉最佳实践和工作流程,以便为您完成正确的事情。

你的反例看起来更简单,因为你不说的话,你会真正与方法。您上面发布的示例显示了一个正在从Memcached中取出的List,添加了一个新项目,有条件地从中删除一些项目,然后将其重新放回。您发布的文本中至少有一半仍需要编写。

如果您不是请使用 CASMutator,您最终将重新发明它,这并非如此简单。这就是它为你今天做的:

public T cas(final String key, final T initial, int initialExp, 
     final CASMutation<T> m) throws Exception { 
    T rv=initial; 

    boolean done=false; 
    for(int i=0; !done && i<max; i++) { 
     CASValue<T> casval=client.gets(key, transcoder); 
     T current=null; 
     // If there were a CAS value, check to see if it's compatible. 
     if(casval != null) { 
      T tmp = casval.getValue(); 
      current=tmp; 
     } 
     // If we have anything mutate and CAS, else add. 
     if(current != null) { 
      // Declaring this impossible since the only way current can 
      // be non-null is if casval was set. 
      assert casval != null : "casval was null with a current value"; 

      rv=m.getNewValue(current); 
      // There are three possibilities here: 
      // 1) It worked and we're done. 
      // 2) It collided and we need to reload and try again. 
      // 3) It disappeared between our fetch and our cas. 
      // We're ignoring #3 because it's *extremely* unlikely and the 
      // behavior will be fine in this code -- we'll do another gets 
      // and follow it up with either an add or another cas depending 
      // on whether it exists the next time. 
      if(client.cas(key, casval.getCas(), rv, transcoder) 
        == CASResponse.OK) { 
       done=true; 
      } 
     } else { 
      // No value found, try an add. 
      if(initial == null) { 
       done = true; 
       rv = null; 
      } else if(client.add(key, initialExp, initial, transcoder).get()) { 
       done=true; 
       rv=initial; 
      } 
     } 
    } 
    if(!done) { 
     throw new RuntimeException("Couldn't get a CAS in " + max 
      + " attempts"); 
    } 

    return rv; 
} 
+0

好吧,你是完全正确的,但你不觉得这个解决方案是相当侵入? – terry 2011-06-15 20:22:19

+0

侵入什么方式?它是在CAS处理器上对处理器进行建模之后建立的,除了在单个关键高竞争位置之外,它应该可以很好地扩展。老实说,Java使它变得更加困难。大多数代码只是一个简单的lambda表达式,在许多语言中。 Java只是带来了一堆语法来包装它。 – Dustin 2011-06-15 21:38:59

+0

在我看来,因为我必须把我的业务代码放在spymemcached getNewValue函数定义中。你不觉得使用一些图案或分离层是不可能的吗? – terry 2011-06-16 21:25:01