Closed GoogleCodeExporter closed 9 years ago
你期望什么结果呢?
Original comment by killme2...@gmail.com
on 21 Jul 2011 at 8:19
无论有没有get这一行,结果都应当是0,我不知道你测试出来�
��结果是什么?你用的memcached是官方提供跑在linux或者mac上的�
��?
Original comment by killme2...@gmail.com
on 21 Jul 2011 at 11:44
试试这个,把下面的第5行的-7改成2然后在试试。之前由于有�
��和没错都变成0了,不好区别。
[code]
Counter counter=client.getCounter("counter",6);
counter.get(); //
counter.incrementAndGet();
counter.decrementAndGet();
counter.addAndGet(2);
System.out.println("counter:"+counter.get());
client.delete("counter");
[/code]
我已经下班了,环境和代码在公司,我现在不方便测试,不��
�还记得之前的结果,我还认真的抓了包分析,发现如果注释�
��第二行的代码,第三行的代码貌似没有任何效果,在抓包中
也没有看到这个请求,后面的代码都是正确的。
如果注释掉,结果是7,如果不注释掉,结果就是8,我记得当
时我反复测试的确是这个结果。Mem的版本是1.4.x
后面小版本号记不住了。明天回公司在看看。
你先测试下,如果结果不是我说的那样,我明天回到公司再��
�试。
Original comment by solosky...@gmail.com
on 21 Jul 2011 at 12:18
正确结果应当为7
这是个bug,主要是在get方法里多了个副作用,当key不存在的��
�候主动add了一次,这是多余的。导致结果会为8。
感谢你的报告,我会修正下。
Original comment by killme2...@gmail.com
on 21 Jul 2011 at 1:04
不客气,但为什么正确的结果是7呢,应该是8吧~
[code]
Counter counter=client.getCounter("counter",6);
counter.get(); //
counter.incrementAndGet(); //counter=7
counter.decrementAndGet(); //counter=6
counter.addAndGet(2);//counter=8
System.out.println("counter:"+counter.get()); //counter=8
client.delete("counter");
[/code]
Original comment by *rongqia...@chuntent.com
on 21 Jul 2011 at 1:12
incrementAndGet或者decrementAndGet在key不存在的时候,会调用add将��
�始值放入,但是不会递增。
Counter的初始值是指当key不存在的时候将该值设置为初始值,�
��次操作不起作用的。
Original comment by killme2...@gmail.com
on 21 Jul 2011 at 1:20
incrementAndGet/incrementAndGet本意是递增或者减少值,API的名字代�
��的含义是明确的,你说“会在key不存在的时候,会调用add将
初始值放入,但是不会递增”,这明显存在二义性,调用这��
�API的行为不明确,这样会造成很不容易调试的错误。
强烈建议将这两个API的行为修改为“在key不存在的时候,会��
�用add将初始值放入,然后执行递增或者递减的操作”,或者�
��在构造Counter的时候检测值是否存在,如果不存在就初始化��
�。
Original comment by solosky...@gmail.com
on 22 Jul 2011 at 1:38
嗯,这是欠考虑的地方,不符合直觉。
但是现在修改可能会破坏已有的代码,我考虑下吧。
Original comment by killme2...@gmail.com
on 22 Jul 2011 at 1:41
另外关于CAS建议封装如下的API,可以更加方便的进行CAS操作��
�
/**
* 封装对CASOpertion的操作,可以指定最大的尝试次数
* @param key 需更新缓存的KEY
* @param value 待更新的缓存的值
* @param maxRetryTimes 最大重试次数
* @return 如果在最大尝试次数内更新成功返回true,否则返回false
*/
public <T> boolean casOperation(String key, final T value, final int maxRetryTimes)
{
return this.cas(key, 0, new CASOperation<T>() {
@Override
public int getMaxTries() {
return maxRetryTimes;
}
@Override
public T getNewValue(long currentCAS, T currentValue) {
return value;
}
});
}
Original comment by solosky...@gmail.com
on 22 Jul 2011 at 1:52
再废话一点,昨天测试的时候发现很客户端很多地方都没有��
�测服务器返回的值是不是ERROR,比如下面的代码
[code]
client.set("good_value", 3000,
"abc"); //不能这样初始化值然后原子递增或递减,否则结果是�
��误
client.incr("good_value", 2, 0);
[/code]
将会抛出下面的异常:
java.lang.NumberFormatException: For input string: "CLIENT_ERROR cannot
increment or decrement non-numeric value"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.valueOf(Unknown Source)
at net.rubyeye.xmemcached.command.text.TextIncrDecrCommand.decode(TextIncrDecrCommand.java:75)
at net.rubyeye.xmemcached.codec.MemcachedDecoder.decode0(MemcachedDecoder.java:59)
at net.rubyeye.xmemcached.codec.MemcachedDecoder.decode(MemcachedDecoder.java:54)
at com.google.code.yanf4j.nio.impl.NioTCPSession.decode(NioTCPSession.java:288)
at com.google.code.yanf4j.nio.impl.NioTCPSession.readFromBuffer(NioTCPSession.java:205)
at com.google.code.yanf4j.nio.impl.AbstractNioSession.onRead(AbstractNioSession.java:198)
at com.google.code.yanf4j.nio.impl.AbstractNioSession.onEvent(AbstractNioSession.java:343)
at com.google.code.yanf4j.nio.impl.SocketChannelController.dispatchReadEvent(SocketChannelController.java:56)
at com.google.code.yanf4j.nio.impl.NioController.onRead(NioController.java:157)
at com.google.code.yanf4j.nio.impl.Reactor.dispatchEvent(Reactor.java:294)
at com.google.code.yanf4j.nio.impl.Reactor.run(Reactor.java:141)
明显是没有检测返回值嘛,希望能完善下。
Original comment by solosky...@gmail.com
on 22 Jul 2011 at 2:29
很多地方应该不至于,我看了下,这个地方确实没检查,感��
�你的报告。
新加api是不准备加入了,你可以自己封装。
Original comment by killme2...@gmail.com
on 22 Jul 2011 at 2:49
/**
* 封装对CASOpertion的操作,可以指定最大的尝试次数
* @param key 需更新缓存的KEY
* @param value 待更新的缓存的值
* @param maxRetryTimes 最大重试次数
* @return 如果在最大尝试次数内更新成功返回true,否则返回false
*/
public <T> boolean casOperation(String key, final T value, final int maxRetryTimes)
我自己还在外边包装了一个重试时间的设置参数,通常操作��
�败都是因为当时网络不稳定,不断重试意义不大,还不如增�
��一个短暂的等待时间再重试。
Original comment by springda...@gmail.com
on 4 Aug 2011 at 12:53
Fixed by
https://github.com/killme2008/xmemcached/commit/979eb04d9fcc1a1fcbb2ff39782ea158
1ca646c5
Original comment by killme2...@gmail.com
on 5 Sep 2011 at 1:24
Original issue reported on code.google.com by
solosky...@gmail.com
on 21 Jul 2011 at 8:08