浏览 4597 次
锁定老帖子 主题:,jedis 用连接池时超时返回值类型错误
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-10-15
at redis.clients.jedis.Connection.getIntegerReply(Connection.java:161) at redis.clients.jedis.Jedis.del(Jedis.java:108) 类似的错误,就是返回值类型和文档上的返回值类型不相符,感觉很不应该;开始怀疑是jedis实现的一个bug,后来发现一个现象,当抛一个超时异常的时候,后面就连续的出现一个类似上面的错误,最后终于发现了问题所在。 原先的代码是这样的: public long del(String key) { long rt = 0L; Jedis jedis = null; try { jedis = getJedis(); rt = jedis.del(key); } finally { releaseJedisInstance(jedis); } return rt; } 这样写貌似OK,但实际上有问题,假设jedis在执行这个命令的时候,因为redis超负荷,jedis可能返回超时的异常,这个时候发生了什么,没有处理这个异常,直接将这个jedis的链接返回到了连接池,这样有没有问题呢? 查看jedis源码发现他的connection中对网络输出流做了一个封装,其中自建了一个buffer,所以当发生异常的时候,这个buffer里还残存着上次没有发送或者发送不完整的命令,这个时候没有做处理,直接将该连接返回到连接池,那么重用该连接执行下次命令的时候,就会将上次没有发送的命令一起发送过去,所以才会出现上面的错误“返回值类型不对”; 所以正确的写法应该是在发送异常的时候,销毁这个连接,不能再重用! 正确的写法如下: public long del(String key) { long rt = 0L; Jedis jedis = null; try { jedis = getJedis(); rt = jedis.del(key); } catch (Exception e) { returnBrokenResource(jedis); } finally { releaseJedisInstance(jedis); } return rt; } 从上面的分析来看,我更认为是jedis实现的一个bug,当连接出现异常的时候,应该对该连接的buffer进行清空的,你认为呢? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-10-26
很好,正在开始学习jedis!
|
|
返回顶楼 | |
发表时间:2011-11-23
能不能把代码都帖一下呢,谢谢!
|
|
返回顶楼 | |