redis異常 ClassCastException cannot be cast to java.lang.Long


/**
     * 釋放連接
     * @param pool
     * @param jedis
     * @param <T>
     */
    public static <T> void releaseConnection(Pool<T> pool, T jedis) {
        if (pool != null && jedis != null) {
            pool.returnResource(jedis);
        }
    }

    /**
     * 超時等異常時清空該對象上次執行命令的結果緩存
     * @param pool
     * @param jedis
     * @param <T>
     */
    public static <T> void clearBuffer(Pool<T> pool, T jedis) {
        if (pool != null && jedis != null) {
            pool.returnBrokenResource(jedis);
        }
    }

錯誤寫法

public Long append(String key, String value) {
		Long l = null;
		List<JedisPool> pools = cluster.getWriteRedisPool(key);
		for(JedisPool pool : pools){
			Jedis jedis = null;
			try {
				jedis = pool.getResource();
				l = jedis.append(key, value);
			} catch (Exception e) {
				throw new RedisException(e);
			} finally{
				ReleaseConnectionUtils.releaseConnection(pool,jedis);
			}
		}
		return l;
	}

程序執行上圖方法時偶爾拋出異常:

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.Long 
at redis.clients.jedis.Connection.getIntegerReply(Connection.java:161) 
at redis.clients.jedis.Jedis.del(Jedis.java:108) 

這樣寫貌似沒問題,但實際上有問題,假設jedis在執行這個命令的時候,因為redis超負荷,jedis可能返回超時的異常,這個時候發生了什么,沒有處理這個異常,直接將這個jedis的鏈接返回到了連接池,這樣有沒有問題呢? 
查看jedis源碼發現他的connection中對網絡輸出流做了一個封裝,其中自建了一個buffer,所以當發生異常的時候,這個buffer里還殘存着上次沒有發送或者發送不完整的命令,這個時候沒有做處理,直接將該連接返回到連接池,那么重用該連接執行下次命令的時候,就會將上次沒有發送的命令一起發送過去,所以才會出現上面的錯誤“返回值類型不對”; 
所以正確的寫法應該是在發送異常的時候,銷毀這個連接,不能再重用!

正確寫法  

public Long append(String key, String value) {
		Long l = null;
		List<JedisPool> pools = cluster.getWriteRedisPool(key);
		for(JedisPool pool : pools){
			Jedis jedis = null;
			try {
				jedis = pool.getResource();
				l = jedis.append(key, value);
			} catch (Exception e) {
				ReleaseConnectionUtils.clearBuffer(pool,jedis);
				throw new RedisException(e);
			} finally{
				ReleaseConnectionUtils.releaseConnection(pool,jedis);
			}
		}
		return l;
	}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM