首页 > 数据库 >如何关闭redis的自动清理缓存,声明式事务(含有redis)如何解决,redis setnx锁的使用。

如何关闭redis的自动清理缓存,声明式事务(含有redis)如何解决,redis setnx锁的使用。

时间:2024-08-09 14:23:07浏览次数:17  
标签:addPageA term 缓存 lock redis Exception setnx new

20240809

一、解决redis数据被删除的方案

1、发现问题

在我们小组进行开发的时候,发现,redis中的数据老是会丢失,刚开始以为是若依的SpringBoot配置问题,一直找,但是,没有发现有关的地方。
然后开始看是不是服务器重启,AOF不保存数据的问题,然后发现没有,那就只有一个了!!!那就是redis的config配置了!!

2、解决

  1. 打开Redis配置文件
  2. 在Redis服务器上,找到redis.conf文件所在的位置,通常位于Redis安装目录下的/etc/redis/目录中。使用文本编辑器打开该文件。

注释掉相关配置项
在打开的redis.conf文件中,搜索以下两个配置项:

auto-aof-rewrite-percentage
auto-aof-rewrite-min-size

修改为

auto-aof-rewrite-percentage 0
auto-aof-rewrite-min-size 0
  1. 保存对redis.conf文件的修改

  2. 重启Redis服务器
    使用以下命令重启Redis服务器,以使修改后的配置生效:
    sudo systemctl restart redis

注意!!

完成以上步骤后,Redis将不再自动进行AOF重写操作,从而关闭了自动清理缓存的功能。
需要注意的是,关闭自动清理缓存可能会导致AOF文件过大而影响性能,因此在实际应用中,需要根据实际情况合理配置AOF重写的触发条件,以及定期手动执行AOF重写操作来清理缓存。

二、声明式事务(当有redis的时候)

1. 先看代码

   @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInspectList(List<Sub> subList) {
        for (Sub sub : subList) {
            SubVo subVo = new SubVo();
            SubDTO subDTO = new SubDTO();
            BeanUtils.copyProperties(sub, subVo);
            BeanUtils.copyProperties(sub, subDTO);

            // 更新 term_production_info
            homePageCMapper.updateInspectA(subVo);

            // 更新 om_term_info
            subDTO.setDevidqi_state(1);
            subDTO.setTerm_qi_devid_qi_time(sub.getDevid_qi_time());
            homePageCMapper.updateInspectB(subDTO);

            // 将 inspect_list 存入 Redis
            String term_sn = sub.getTerm_sn();
            List<Inspect> configList = sub.getInspect_list();
            for (Inspect inspect : configList) {
                if(Objects.equals(inspect.getResult(), "ok")){
                    inspect.setResult("1");
                }else {
                    inspect.setResult("2");
                }
            }
            try {
                stringRedisTemplate.opsForValue().set("configList:" + term_sn, JSONUtil.toJsonStr(configList));
            } catch (Exception e) {
                stringRedisTemplate.delete("configList:" + term_sn);
                Console.error("Redis创建数据失败", e);
                throw e;
            }
        }
    }

2. @Transactional(rollbackFor = Exception.class)

声明式事务,根据捕获的异常进行回滚。 Exception.class这是很多异常的父类

 @Transactional(rollbackFor = Exception.class)

3. 如何解决redis在事务里面,如何保证原子性和一致性

3.1 我们可以用try catch finally来实现

当遇到错误的时候,我们可以在最后执行到finally来删除我们在这个里面创建的redis或者修改数据回去,从而避免数据不一致或部分更新的情况。。

3.2 我们可以让redis的执行放到最后,这样当其他的

我们也可以直接在最后执行redis,然后对他进行try cath。只有在上面的所有操作都执行完毕之后,才会执行redis,然后对redis的操作进行判断,如果是redis出错了,就只用看抛出的异常然后操作redis。

三、使用分布式锁(redis)

1. 先看代码

@Transactional(rollbackFor = Exception.class)
    @Override
    public void Add(AddPageA addPageA) {
    String lockKey = "lock_key";
    Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "locked", 10, TimeUnit.SECONDS);
    if (lock != null && lock) {
    try {
        OmTermInfoDTO omTermInfoDTO = new OmTermInfoDTO();
        OutTermShipDTO outTermShipDTO = new OutTermShipDTO();

        BeanUtil.copyProperties(addPageA, omTermInfoDTO);
        BeanUtil.copyProperties(addPageA, outTermShipDTO);

        outTermShipDTO.setBom_no(addPageA.getOut_term_ship_bom_no());
        omTermInfoDTO.setCreat_time(new Date());
        /*omTermInfoDTO.setOut_term_ship_ship_time(addPageA.getShip_time());
        omTermInfoDTO.setOut_term_ship_take_address(addPageA.getTake_address());*/
        outTermShipDTO.setTake_address(addPageA.getOut_term_ship_take_address());
        outTermShipDTO.setShip_time(addPageA.getOut_term_ship_ship_time());


        List<String> regionData = new ArrayList<>();
        regionData = addPageA.getOut_region_name_no();
        String term_sn = addPageA.getTerm_sn();

        stringRedisTemplate.opsForValue().set(term_sn + ":region", JSONUtil.toJsonStr(regionData));
        // 获取集合
        List<String> list = addPageA.getOut_region_name_no();

        // 获取集合的最后一位
        int lastElement = Integer.parseInt(list.get(list.size() - 1));
        omTermInfoDTO.setOut_region_id(lastElement);
        addMapper.AddOmTerInfo(omTermInfoDTO);
        addMapper.AddOutTerShip(outTermShipDTO);
        }catch (Exception e){
        throw new RuntimeException("代码异常");
    }
    finally {
          stringRedisTemplate.delete(lockKey);
        }
        }else {
            throw new RuntimeException("Could not acquire lock");
        }
    }

2. 为什么要使用

因为我在一次操作中,连点了好几次,就发现数据和预想不一样,多了一条,所以,针对于这样的操作,就需要进行加锁。

3. 使用的redis的 setnx进行加锁

先定义一个key,然后进来一个线程需要先去获取锁,如果拿到就执行,拿不到就没了,哈哈哈,没有重试啊,因为它不是多线程吧,这个稍后在研究。
最后执行完之后,释放这个锁,下次就能实现了。

  String lockKey = "lock_key";
    Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "locked", 10, TimeUnit.SECONDS);
    if (lock != null && lock) {
    try{
    }
     finally {
          stringRedisTemplate.delete(lockKey);
        }
    }else {
            throw new RuntimeException("无法拿到锁");
        }

    

标签:addPageA,term,缓存,lock,redis,Exception,setnx,new
From: https://blog.csdn.net/f552126506/article/details/141060744

相关文章

  • Redis笔记
    Redis(Remotedictionaryserver)开源的基于内存的数据存储系统可用于数据库、缓存、队列等各种场景。支持key-value的储存形式,底层是用C语言编写的。基于key-value形式的数据字典,结构非常简单,没有数据表的概念,之间用键值对的形式完成数据的管理。SQL NoSQL数据结构结构......
  • docker 构建redis
    一、Docker搜索redis镜像dockersearchredis 二、Docker拉取镜像dockerpullredis 三、Docker挂载配置文件接下来就是要将redis的配置文件进行挂载,以配置文件方式启动redis容器。(挂载:即将宿主的文件和容器内部目录相关联,相互绑定,在宿主机内修改文件的话也随之修改容......
  • dockker部署redis报错(报:WARNING Memory overcommit must be enabled! Without it, a b
    转载博客(机翻):https://ourcodeworld.com/articles/read/2083/how-to-remove-redis-warning-on-docker-memory-overcommit-must-be-enabledHowtoremoveRediswarningonDocker:Memoryovercommitmustbeenabled如何删除Docker上的Redis警告:必须启用内存过量使用Carlos......
  • Yum缓存包
    简单介绍 使用系统版本:[root@localhost~]#uname-aLinuxlocalhost5.14.0-427.13.1.el9_4.x86_64#1SMPPREEMPT_DYNAMICWedMay119:11:28UTC2024x86_64x86_64x86_64GNU/Linux[root@localhost~]#cat/etc/os-releaseNAME="RockyLinux"VERSION="9.......
  • Java后端面试题(redis相关1)(day7)
    目录为什么要用Redis?Redis到底是多线程还是单线程?Redis数据持久化机制RDB方式AOF方式Redis是单线程,但为什么快?Redis过期删除策略Redis内存淘汰策略为什么要用Redis?基于内存操作,内存读写速度快支持多种数据类型,包括String、Hash、List、Set、ZSet等支持持久化,Redi......
  • Redis连接问题解决汇总
    Redis连接失败常见解决方案1.检查Redis命令行是否可以正常连接使用命令行客户端,输入:redis-cli-h虚拟机ip地址-p6379-aredis访问密码如若连接成功,输入ping,看控制台是否返回PONG此步骤若正常,则代表虚拟机可正常连接2.Redis命令行无法正常连接1)未打开Redis6379端口......
  • Redis学习笔记_1_基本安装与使用
    Redis入门篇1初识RedisRedis是一种键值型的NoSql数据库键值型:指Redis中存储的数据都是以key、value对的形式存储,而value的形式多种多样,可以是字符串、数值、甚至jsonNoSql:相对于传统关系型数据库而言,有较大差异1.1认识NoSQLNoSql可以翻译做NotOnlySql(不仅仅是SQL......
  • redis的持久化(2)
    1.背景 众所周知redis是一个内存数据库,所以他的运行效率特别高。但是也存在一个问题:因为内存中的数据不是持久的,所以当redis宕机或者关机重启,那内存中的数据就全部丢失了。 当然这肯定是不允许的,redis是具有持久化机制的,它会通过设置 以快照或者操作日志的形式将数据持......
  • Redis-Sentinel部署记录
    目录Sentinel哨兵模式介绍Sentinel状态持久化Sentinel作用Sentinel工作方式(每个Sentinel实例都执行的定时任务)三个定时监控任务Sentinel搭建过程所有主机创建sentinel目录所有主机创建sentinel配置文件启动sentinel模拟主库宕机Sentinel常用命令PINGSENTINELmasterSENTINELslave......
  • Redis-主从复制部署记录
    目录主从模式介绍作用工作原理全量同步增量同步主库是否要开启持久化?主从搭建过程主机规划下载redis安装依赖关闭防火墙编译安装redis所有主机配置环境变量所有主机创建Redis的数据存储目录所有主机创建配置文件启动redis使用system管理启动警告处理开启主从从库开启主从主库查看......