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失败的解决办法的文章就介绍到这了,更多相关SpringBoot RedisTemplate.delete删除指定key内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java使用RedisTemplate模糊删除key操作

    Redis模糊匹配批量删除操作,使用RedisTemplate操作: public void deleteByPrex(String prex) { Set<String> keys = redisTemplate.keys(prex); if (CollectionUtils.isNotEmpty(keys)) { redisTemplate.delete(keys); } } prex为迷糊匹配的key,如cache:user:* 这里需要判断keys是否存在,如果一个都匹配不到会报错:

  • 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,缓存中的对象是一坨乱码,让人眼花缭乱,这

  • redis删除指定key的实现步骤

    1.打开redis目录并打开redis-cli.exe 如果直接输入get key会出现以下问题,表示需要认证,也就是需要登录用户 使用auth password登录即可 然后使用get key获取键的值 确认后,使用del key删除键中的值,可多个删除 到此这篇关于redis删除指定key的实现步骤的文章就介绍到这了,更多相关redis删除指定key内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

  • 浅谈MySQL安装starting the server失败的解决办法

    如果电脑是第一次安装MySQL,一般不会出现这样的报错.如下图所示.starting the server失败,通常是因为上次安装的该软件未清除干净. 完全卸载该软件的办法: 第一步,进入-控制面板\程序\程序和功能,卸载下图中的MySQL两个软件. 第二步,删除上次安装目录的MySQL残留文件,更不要忘了删除ProgramData下的MySQL文件夹,如下图所示.注意:这里的文件夹与上次安装目录里的残留文件不同,C:\ProgramData 一般默认是隐藏的. 第三步,Win+R 输入 reg

  • 关于AES加密算法在linux下解密失败的解决办法

    前段时间项目要部署到linux上时遇到了这个问题,百度一下找到了解决方案,在这分享一下: public class RSAEncrypt { // 密钥 private static Key key; // KEY种子 private static String KEY_STR = "keyString"; // 常量 public static final String UTF_8 = "UTF-8"; public static final String AES

  • Android 中Failed to read key from keystore解决办法

    Android 中Failed to read key from keystore解决办法 Caused by: org.gradle.tooling.BuildException: Failed to read key from keystore at com.android.build.gradle.tasks.PackageApplication.doFullTaskAction(PackageApplication.groovy:110) at com.android.build.gra

  • phpStudy访问速度慢和启动失败的解决办法

    下面给大家介绍phpstudy访问速度慢的解决办法. 1.修改mysql数据库链接地址为ip地址127.0.0.1. 2.使用最新版本,这个坑了我好久时间. 下面一段内容是关于phpstudy启动失败的解决办法. php5.3.5.4和apache都是用vc9编译,电脑必须安装vc9运行库才能运行. php5.5.5.6是vc11编译,如用php5.5.5.6必须安装vc11运行库. vc9和vc11运行库下载:http://pan.baidu.com/s/1gd0y1Qb php5.5以上才有

  • 百度地图API提示230 错误app scode码校验失败的解决办法

    笔者近2天在 Android Studio上玩了一下百度地图,碰到了常见的"230错误 APP Scode校验失败",下面我来介绍一下具体的解决办法. 1.在andriodstudio上部署百度地图的规范.把下载下来的SDK解压,切换至Project视图.复制以下3个文件到libs文件下. 跟我申请AK时候sha1完全不一样.所有地图只显示方格子,没有地图加载.并提示"230错误 APP Scode校验失败".去API控制台修改SHA1与Logcat对应,地图加载成

  • pyinstaller 3.6版本通过pip安装失败的解决办法(推荐)

    本机中原pyinstaller版本为3.5版本,本打算通过 pip install --upgrade pyinstaller进行升级,竟然报错,后面卸载再重新安装也一样报错,没办法看来通过pip是暂时安装不上了. 下面就讲解源码安装的方式,先从pypi.org中下载对应3.6版本的源码 https://pypi.org/project/PyInstaller/#files 下载完成后如果是win10操作系统的话,一定要以管理员的方式打包命令窗口,否则会提示权限不足的问题,比如我是把源码放到E盘

  • win2003 HookPort 服务启动失败的解决办法!

    问题描述:Win2003系统每次开机启动时都弹出个对话框报HookPort 服务启动失败,很多网友都遇到同类问题,问题根源是360安全卫士引起的,官方一直没有给出解决方案,去他们论坛上发贴也没人理,哥只有自己处理了,现在发上来和广大网友们共享! 解决办法: 1.删除360安全卫士或升级他们的软件试下: 2.如果上面的办法不中那就用哥的吧,把下面的代码存成一个bat文件,然后双击即可,双击后再重启一次看看,是不是不报了?是不是很神奇呀,哈哈! ,哥的QQ285584,欢迎交流! 程序代码 复制代码

  • sql server 2008安装失败的解决办法 彻底卸载老版本!

    有很多人在装sql server的时候,稍有不慎就安装失败.sql server 2008应该是用的比较多的,很多人都遇到了安装失败的问题,什么原因造成的呢?小编这里简单的总结了下,并为大家带来解决办法,不妨试试哦! 如图:安装失败都是因为以前的老版本未卸载干净造成的! 怎么解决? 1.停止所有跟Sql相关的服务:控制面板-〉管理工具-〉服务 2.在控制面板中卸载所有和SQL有关的一切程序或者组建 3.注册表清理(): 3.1彻底删除SQL Server: hkey_local_machine\

随机推荐