IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> SpringBoot整合Redis事务特性实践整理 -> 正文阅读

[大数据]SpringBoot整合Redis事务特性实践整理

原理

首先 Redis 是支持一定事务能力的 NoSQL,在 Redis 中使用事务,通常的命令组合是 watch… multi…exec,也就是要在一个 Redis 连接中执行多个命令,这时我们可以考虑使用 SessionCallback 接口来达到这个目的。
其中,watch 命令是可以监控 Redis 的一些键;multi 命令是开始事务,开始事务后,该客户端的命令不会马上被执行,而是存放在一个队列里,这点是需要注意的地方,也就是在这时我们执行一些返回数据的命令,Redis 也是不会马上执行的,而是把命令放到一个队列里,所以此时调用 Redis 的命令,结果都是返回 null,这是初学者容易犯的错误;exec 命令的意义在于执行事务,只是它在队列命令执行前会判断被 watch 监控的 Redis 的键的数据是否发生过变化(即使赋予与之前相同的值也会被认为是变化过),如果它认为发生了变化,那么 Redis 就会取消事务,否则就会执行事务,Redis 在执行事务时,要么全部执行,要么全部不执行,而且不会被其他客户端打断,这样就保证了 Redis 事务下数据的一致性。下图就是 Redis 事务执行的过程。
在这里插入图片描述

实践

redis事务简单示例

@GetMapping("/exec")
    public ResponseEntity exec() {
        // 添加一条测试基础数据
        redisTemplate.opsForValue().set("key1", "张三");
        // 使用SessionCallback保持执行的原子性
        List list = (List) redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations redisOperations) throws DataAccessException {
                // 设置要监控的key,注意这里使用的是当前接口的RedisOperations对象
                redisOperations.watch("key1");
                // 开启事务,在 exec 命令执行前,全部都只是进入队列
                redisOperations.multi();
                // 事务内的一些代码
                redisOperations.opsForValue().set("key2", "Pete2");
                redisOperations.opsForValue().set("key3", "Pete3");
                // 执行 exec 命令,将先判别 key1 是否在监控后被修改过,如果是则不执行事务,否则就执行事务
                return redisOperations.exec();
            }
        });
        return ResponseEntity.ok(list);
    }

上面是一个redis事务使用的简单案例
【1】其中设置key2和key3是在一个连接事务中,它们要么一起成功要么一起失败。
【2】redisOperations.exec();是事务执行的关键方法,执行 exec 命令,将先判别 key1 是否在监控后被修改过,如果是则不执行事务,否则就执行事务。
【3】场景测试:以debug方式执行该代码,并在redisOperations.exec();处打上断点,即先让exec()不执行,然后此时去修改redis服务器中key1的值,可以修改其中的value或者删除key都可以,此时即表示watch监听的数据发生了变化,接着断点放开,上面的代码执行未报错,但是key2和key3的值并没有完成写入。
【4】因为程序中先使得 Redis的 watch 命令监控了 key1 的值,而后的 multi 让之后的命令进入队列,而在 exec 方法运行前我们修改了 key1,根据 Redis 事务的规则,它在 exec 方法后会探测 key1 是否被修改过,如果没有则会执行事务,否则就取消事务,所以 key2 和 key3 没有被保存到 Redis 服务器中。
【5】上面的redisTemplate.execute执行结果返回是一个List,如果执行了则该命令为true,否则为空。

redis事务测试异常

 /**
     * redis事务测试异常
     */
    @GetMapping("/testException")
    public ResponseEntity testException() {
        redisTemplate.opsForValue().set("key1", "张三");
        List list = (List) redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations redisOperations) throws DataAccessException {
                redisOperations.watch("key1");
                redisOperations.multi();
                redisOperations.opsForValue().set("key2", "Pete2");
                // 对一个字符串数据执行增加操作,当前操作会失败
                redisOperations.opsForValue().increment("key1", 1);
                redisOperations.opsForValue().set("key3", "Pete3");
                return redisOperations.exec();
            }
        });
        return ResponseEntity.ok(list);
    }

上面示例中需要注意在于redisOperations.opsForValue().increment(“key1”, 1); 这里对一个字符串类型的值做了相加操作,这个是会抛出异常的,无法执行该操作。
在这里插入图片描述
同样地,我们运行这段代码后,可以看到服务器抛出了异常,然后我们去 Redis 服务器查询 key2 和 key3,可以看到它们已经有了值。
在这里插入图片描述
注意,这就是 Redis 事务和数据库事务的不一样,对于 Redis 事务是先让命令进入队列,所以一开始它并没有检测这个加一命令是否能够成功,只有在 exec 命令执行的时候,才能发现错误,对于出错的命令 Redis 只是报出错误,而错误后面的命令依旧被执行,所以 key2 和 key3 都存在数据,这就是 Redis 事务的特点,也是使用 Redis 事务需要特别注意的地方。为了克服这个问题,一般我们要在执行 Redis 事务前,严格地检查数据,以避免这样的情况发生。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:22:24  更:2022-10-22 21:26:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/4 6:46:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码