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 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> springboot使用redis事务 -> 正文阅读

[Java知识库]springboot使用redis事务

事务处理

redis事务提供了一种“将多个命令打包, 然后一次性、按顺序地执行”的机制, 并且事务在执行的期间不会主动中断 —— 服务器在执行完事务中的所有命令之后, 才会继续处理其他客户端的其他命令。
Redis中的事务是可以视为一个队列,即我们可以通过MULTI开始一个事务,这相当于我们声明了一个命令队列。
接下来,我们向Redis中提交的每条命令,都会被排入这个命令队列。
当我们输入EXEC命令时,将触发当前事务,这相当于我们从命令队列中取出命令并执行,所以Redis中一个事务从开始到执行会经历 开始事务命令入队执行事务 三个阶段。
?

# 开启事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name "walker"
QUEUED #会将执行命令加入队列中
127.0.0.1:6379> sadd list 1 2 3 4 5
QUEUED 
127.0.0.1:6379> get name  # 此时获取结果是获取不到的,只会显示QUEUED字段
QUEUED


# 执行队列命令
127.0.0.1:6379> exec
1) OK
2) (integer) 5
3) "walker"

?

  • 事务是由一系列操作组成的单个逻辑工作执行单元。特别地,因为在Redis中命令是存储在一个队列中,所以,事务中的所有命令都会按顺序执行,并且在执行事务的过程中不会被客户端发送的其它命令中断。
  • 事务是一个原子操作,事物中的命令只有两种执行结果,即全部执行或者全部不执行。如果客户端在使用MULTI命令开启事务后因为意外而没有执行EXEC命令,则事务中的所有命令都不会执行。同理,如果客户端在使用MULTI命令开启事务后执行EXEC命令,则事务中的所有命令都会执行。
  • Redis中的事务可以使用DISCARD命令来清空一个命令队列,并放弃对事务的执行。如果命令在入队时发生错误,Redis将在客户端调用EXEC命令时拒绝执行并取消事务,但是在EXEC命令执行后发生的错误,Redis将选择自动忽略。

相关指令

multi

标记一个事务块的开始。

exec

执行所有事务块的命令

discard

取消事务,放弃执行事务块内的所有命令。
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a1 name
QUEUED
127.0.0.1:6379> set a2 test
QUEUED
127.0.0.1:6379> get a2
QUEUED

# 清除队列命令
127.0.0.1:6379> discard
OK

# 之后获取就获取不到queue队列了
127.0.0.1:6379> get a2
(nil)
127.0.0.1:6379> get a1
(nil)

watch

Redis Watch 命令用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断

WATCH key [key ...]

springboot事务使用

开启事务

方式一

@Autowired
    private RedisTemplate redisTemplate;


    /**
    * 事务方式一
    */
    @Test
    void testTransaction(){
        //开启事务支持   
        //记得开启事务支持,但是不知道为何,我已经开启了,结果还是出现“ ERR EXEC without MULTI”,找不到原因,可能是redis版本问题
        redisTemplate.setEnableTransactionSupport(true);
        //开启事务
        redisTemplate.multi();
        ValueOperations<String, String> stringops = redisTemplate.opsForValue();
        String key="test:transaction";
        stringops.set(key,"1");
        ListOperations<String, String> listOps = redisTemplate.opsForList();
        String key1="test:transaction2";
        listOps.leftPush(key1,"1111");
        System.out.println(stringops.get(key));
        System.out.println(listOps.range(key1, 0, 10));
        //执行事务
        redisTemplate.exec();
        System.out.println(stringops.get(key));
        System.out.println(listOps.range(key1, 0, 10));

    }

方式二:使用SessionCallback

/**
    * 执行事务方式二
     * 这种方式网友们比较推荐
    */
    @Test
    public void testTransaction2(){
        redisTemplate.execute(new SessionCallback<List<Object>>(){
            @Override
            public List<Object> execute(RedisOperations operations) throws DataAccessException {
                operations.multi();
                operations.opsForValue().set("name:1","walker11");
                operations.opsForValue().set("name:2","walker22");
                operations.opsForValue().set("name:3","walker33");
                return redisTemplate.exec();
            }
        });
    }

使用discard取消事务

 /**
    * 测试取消事务
    */
    @Test
    public void testDiscard(){
        Integer flag=1;
        redisTemplate.execute(new SessionCallback<List<Object>>(){
            @Override
            public List<Object> execute(RedisOperations operations) throws DataAccessException {
                operations.multi();
                operations.opsForValue().set("name:1","walker11");
                operations.opsForValue().set("name:2","walker22");
                operations.opsForValue().set("name:3","walker33");
                if(flag.equals(1)){
                    //取消事务,经测试,在使用discard之后,不能再次执行exec(),否则会出现 ERR EXEC without MULTI错误
                    redisTemplate.discard();
                    return null;
                }
                return redisTemplate.exec();
            }
        });
    }

参考文章:https://zhuanlan.zhihu.com/p/146865185

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 15:57:54  更:2022-03-03 16:02:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:05:26-

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