防止与spymemcached冲突

| 我正在尝试将spymemcached 2.6与更新同步使用,我发现了以下两种使用方式: 使用CASMutation定义CASMutator,这是一种非常侵入性的实现方式,请看一个示例:
public List<Item> addAnItem(final Item newItem) throws Exception {

    // This is how we modify a list when we find one in the cache.
    CASMutation<List<Item>> mutation = new CASMutation<List<Item>>() {

        // This is only invoked when a value actually exists.
        public List<Item> getNewValue(List<Item> current) {
            // Not strictly necessary if you specify the storage as
            // LinkedList (our initial value isn\'t), but I like to keep
            // things functional anyway, so I\'m going to copy this list
            // first.
            LinkedList<Item> ll = new LinkedList<Item>(current);

            // If the list is already \"full\", pop one off the end.
            if(ll.size() > 10) {
                ll.removeLast();
            }
            // Add mine first.
            ll.addFirst(newItem);

            return ll;
        }
    };

    // The initial value -- only used when there\'s no list stored under
    // the key.
    List<Item> initialValue=Collections.singletonList(newItem);

    // The mutator who\'ll do all the low-level stuff.
    CASMutator<List<Item>> mutator = new CASMutator<List<Item>>(client, transcoder);

    // This returns whatever value was successfully stored within the
    // cache -- either the initial list as above, or a mutated existing
    // one
    return mutator.cas(\"myKey\", initialValue, 0, mutation);
}
或使用
cas
方法
cas(String key, long casId, Object value)
完成后:
gets(String key, Transcoder<T> tc) 
第二个实际上更简单,我理解为什么要使用CASMutation ... 我真的很高兴收到有关此bedbase客户端使用的反馈。     
已邀请:
        CASMutator / CASMutation捕获最佳实践和工作流程,以便为您完成正确的事情。 您的反例看起来更简单,因为您没有在说这些方法的实际用途。您上面发布的示例显示了一个列表,该列表已从memcached中拉出,向其中添加了一个新项目,有条件地从中删除了一些项目,然后放回去。您发布的文字至少有一半仍需要写。 如果您不使用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;
}
    

要回复问题请先登录注册