中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot使用RedisTemplate.delete刪除指定key失敗怎么解決

發布時間:2022-03-23 17:45:26 來源:億速云 閱讀:710 作者:iii 欄目:開發技術

本篇內容介紹了“SpringBoot使用RedisTemplate.delete刪除指定key失敗怎么解決”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

問題概述

關于這個問題呢,還是主要出現在項目開發的管理上面,先描述哈項目環境:

1、Java 使用的 JDK-1.8

2、Spring Boot 使用的 Spring Boot-2.0.3

3、Redis 使用的是 2.0.8

4、Jedis 使用的是 2.9.0

(當然其它就不再描述了)

起先,使用的都是原生的 ReidsTemplate API 進行系統緩存的管理工作。后來,由于涉及到對象相關的操作,此時如果還使用原生API,緩存中的對象是一坨亂碼,讓人眼花繚亂,這是就需要自定義序列化機制了,而那位同事就默默的添加上了,在團隊中沒有任何的反饋。

當然,在系統緩存的管理與操作中,博主依然淡定的使用著 RedisTemplate 原生的 API 呢,然后在某天前,測試團隊那邊突然就炸開了鍋,各種問題。。。

現象:通過 Redis 的原生 API 刪除緩存中的 Key 后,系統無任何的報錯信息,并提示刪除成功,再進入到 Redis 服務器上查看應該被刪除的 Key 依然存在,懵逼了!!!

解決辦法

經過一段艱辛的 BUG 排查,再加上各種姿勢查看 Redis 源碼,終于把問題給解決了,貼上一段 Redis 源碼如下:

    public void afterPropertiesSet() {
        super.afterPropertiesSet();
        boolean defaultUsed = false;
        if (this.defaultSerializer == null) {
            this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
        }
 
        if (this.enableDefaultSerializer) {
            if (this.keySerializer == null) {
                this.keySerializer = this.defaultSerializer;
                defaultUsed = true;
            }
 
            if (this.valueSerializer == null) {
                this.valueSerializer = this.defaultSerializer;
                defaultUsed = true;
            }
 
            if (this.hashKeySerializer == null) {
                this.hashKeySerializer = this.defaultSerializer;
                defaultUsed = true;
            }
 
            if (this.hashValueSerializer == null) {
                this.hashValueSerializer = this.defaultSerializer;
                defaultUsed = true;
            }
        }
 
        if (this.enableDefaultSerializer && defaultUsed) {
            Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
        }
 
        if (this.scriptExecutor == null) {
            this.scriptExecutor = new DefaultScriptExecutor(this);
        }
 
        this.initialized = true;
    }

《 Redis 源碼地址 》

注意到 Redis 的默認序列化機制 “ defaultSerializer ” ,如果沒有自定義的序列化機制,則系統默認使用的是 “ org.springframework.data.redis.serializer.JdkSerializationRedisSerializer ” ,然后有老鐵又再系統中默默的自定義了 Redis 的序列化機制,部分示例代碼如下:

package com.btc.common.config;
 
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
 
 
@Configuration
@EnableCaching
public class RedisConfig
        extends CachingConfigurerSupport
{
    @Bean
    public CacheManager cacheManager(final RedisConnectionFactory redisConnectionFactory)
    {
        RedisCacheManager.RedisCacheManagerBuilder builder
                = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory);
 
        return builder.build();
    }
 
    @Bean(name = "springSessionDefaultRedisSerializer")
    public GenericJackson2JsonRedisSerializer getGenericJackson2JsonRedisSerializer()
    {
        return new GenericJackson2JsonRedisSerializer();
    }
 
    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Object, Object> getRedisTemplate(
            final RedisConnectionFactory connectionFactory
    )
    {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        // 配置默認的序列化器
        redisTemplate.setDefaultSerializer(getGenericJackson2JsonRedisSerializer());
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // 設置 Key 的默認序列化機制
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        return redisTemplate;
    }
}

在這段代碼中,根據需求將 Redis Key 的序列化機制更改為了 “ org.springframework.data.redis.serializer.StringRedisSerializer ” (主要目的為避免出現亂碼的象限,其實還是能正常的的使用,只是我們肉眼看到為亂碼而已),并且將 redisTemplate 定義為了類型為泛型的類型。

這兒就是問題的所在,此時就不能使用原生的 “ RedisTemplate redisTemplate; ” 而需要定義為泛型的 “ RedisTemplate <Object,Object> redisTemplate; ” 了,因為當我們再次新增的 key 的時候,使用的是 “ StringRedisSerializer ”序列化機制,但是在 delete 操作的時候是使用的是原生 API ,redis 中的 redisTemplate 默認序列化機制采用的是 “ JdkSerializationRedisSerializer ”,這樣以來,即使你使用 hasKey 方法也會發現 redis 中存在這個 key ,但是實際 hasKey 返回 false,所以就會出現刪除成功,但是實際的數據依然存在 Redis 服務器上咯。

“SpringBoot使用RedisTemplate.delete刪除指定key失敗怎么解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

涞源县| 曲阜市| 浪卡子县| 木兰县| 牙克石市| 平山县| 麦盖提县| 丰原市| 万宁市| 庆云县| 大丰市| 高平市| 塔城市| 中江县| 金门县| 延边| 巨野县| 盖州市| 黄石市| 新巴尔虎右旗| 喀喇沁旗| 蓝山县| 东丽区| 佳木斯市| 湘乡市| 中西区| 东乌| 古浪县| 页游| 固镇县| 武川县| 诸暨市| 邵阳县| 庆元县| 绥棱县| 博客| 罗甸县| 白银市| 瑞丽市| 甘泉县| 恩平市|