Java开发 - Redis事务怎么用?
前言
最近博主感觉捅了Redis窝,从Redis主从,哨兵,集群,集群原理纷纷讲了一遍,不知道大家都学会了多少,想着送佛送到西,不如再添一把火,所以今天带给大家的博客是Redis事务!有人要问,什么?Redis也有事务?没错,Redis也有类似于MySQL的事务,不要惊奇,这也不是刚刚有,只是很多人平时不常用罢了。
事务
事务我们知道,是存在于关系型数据库中的一种数据处理手段,主要责任是数据的CRUD,还包括了事务提交和回滚。那么在Redis里,有没有一种机制也能处理数据的提交和回滚呢?答案是肯定的,那就是Redis事务,它是一个类原子的隔离操作,将一系列指令按需排队并顺序执行,期间不会被其他指令插队。但,Redis事务在运行时无法预测,所以也无法回滚。
指令
在Redis事务中,共有三大指令:
- multi:开启事务
- exec:执行事务
- discard:取消事务
在multi之后开启事务,此时可以set多个key,这些key将按照顺序存入先进先出的队列,exec执行事务,这些事务将按照入队的顺序执行,在这些事务执行过程中,不受其他的插入指令影响。在组队阶段使用discard指令,由于未使用exec指令开启事务,所以前面队列中的操作将全部取消。
我们来做个演示,首先开启一个Redis服务:
redis-server redis1.conf
连接redis:
redis-cli -h localhost -p 6379
正常执行
取消执行
因为没有执行exec,所以discard后,前面的c和d都不会执行。
组队错误
可以看到,在组队时抱了错,事务是不会执行的。
执行错误
我们在set c之后对c进行+1操作,由于c不是integer类型,所以报错了,但是我们发现,最终c和d被存储进了redis,从这一点来看,运行过程中的异常不会导致队列中的任务取消。
Redis和锁
为了保证数据的安全性,我们有时候在做key的存储的时候会给key加锁,防止多个线程的情况下key被篡改去情况发生,一般发生在抢购/秒杀时对库存的操作上。
被关锁就不再多提了,使用被关锁可以完全防止key被篡改,但相应的,线程也将被阻塞,降低效率,这里说说乐观锁在redis里的使用,我们看如下操作。
首先我们需要再开一个命令行,模拟两个线程的场景:
在开始前,我们先通过flushdb指令清空redis中的数据:
监听key并开启事务
线程1:
线程2:
操作并提交key
线程1:
线程2:
可以看到线程2在对a+1的时候出问题了,返回nil。像不像CAS,没错,乐观锁的本质就是CAS,比较并交换,比较的值被改变了,自然不会存入新值。
回滚与原子性
Redis回滚
那有人要问了 ,redis到底能不能回滚?其实在上面我们已经得到了答案,就是在组队阶段是可以回滚的,看“组队错误”,在执行阶段是不支持回滚的,看“执行错误”。
所以,最终我们得出结论,在使用中,redis可支持回滚,但是情况比较复杂,是一种可预知的错误,而那些不可预知的错误,则是无法回滚。
原子性
基于以上redis事务执行时出现的组队和执行问题,所以利用redis做库存的扣减似乎是一件不太稳妥的事,所以,为了弥补这个缺陷,我们需要使用redis的原子性。原子性的特点就是:要么一起执行,要么不执行。这里我们应该都听说一个东西叫lua脚本,其特点我就不多说了,总之就是执行快且保证原子性(不被打断),但是,lua脚本也不支持回滚,所以关于redis的回滚,大家就不要纠结了。
Spring Boot接入Redis事务
关于Spring Boot接入Redis事务,怎么说呢?感觉没太大必要,哈哈,不过也不能说一无是处,用还是有人在用的,这里博主就简单讲讲怎么用。
启动Redis服务
上面Redis已经启动了,直接用。
redisTemplate使用事务
添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
添加配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
准备测试代码
@Testvoid testTransaction() {//开启事务支持redisTemplate.setEnableTransactionSupport(true);//开启事务redisTemplate.multi();redisTemplate.opsForValue().set("name1", "codingfire1");redisTemplate.opsForValue().set("name2", "codingfire2");//执行事务redisTemplate.exec();System.out.println(redisTemplate.opsForValue().get("name1"));System.out.println(redisTemplate.opsForValue().get("name2"));}
以上代码在运行的时候发现报错了:
但是当我打开redis可视化工具查看时发现数据已经存进去了:
官方是通过Jedis来实现事务的,所以这个问题出现了还让人有点懵,很多人说是因为没开启事务支持,但是博主明显开启了,所以有些无从解答了,有知道原因的可以告诉博主。
但是活人不能让尿憋死啊,有一种SessionCallback的方式是很多人都推荐使用的,我们来看看:
@Testpublic void testTransaction2(){redisTemplate.execute(new SessionCallback<List<Object>>(){@Overridepublic List<Object> execute(RedisOperations operations) throws DataAccessException {operations.multi();operations.opsForValue().set("name3","codingfire3");operations.opsForValue().set("name4","codingfire4");operations.opsForValue().set("name5","codingfire5");return redisTemplate.exec();}});}
执行后没报错,我们看下redis可视化工具:
测试成功。
Jedis引入
我们刚刚提到了一种Jedis实现的方式,下面我们来说说Jedis怎么实现。
添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.3.0</version>
</dependency>
添加配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
准备测试代码
@Testpublic void testTransaction3(){Jedis jedis =new Jedis("127.0.0.1",6379);;//开启事务Transaction transaction = jedis.multi();try {transaction.set("key1", "v1");//制造异常,测试取消事务//int i=1/0;transaction.set("key2", "v2");//执行事务transaction.exec();}catch (Exception e){//取消事务transaction.discard();e.printStackTrace();}}
查看redis可视化工具:
测试成功。
结语
以上是对redis事务的一个实操过程,建议大家在做key的存入的时候不要对多个key进行关联,主要是避免出现数据不一致的情况。整体上就是这样,推荐使用SessionCallback和Jedis的方式,虽然你可能不一定会用到这东西,但是万一用到了呢?
相关文章:

Java开发 - Redis事务怎么用?
前言 最近博主感觉捅了Redis窝,从Redis主从,哨兵,集群,集群原理纷纷讲了一遍,不知道大家都学会了多少,想着送佛送到西,不如再添一把火,所以今天带给大家的博客是Redis事务ÿ…...
Windows Server 2019安装使用PostgreSQL 15
主要是参考这篇文章来做的: Windows11安装配置PostgreSQL(图文详细教程)_win11安装postgres 并管理工具_return strxi的博客-CSDN博客 1. 下载的是postgresql 15.3 windows x64-86版本 Community DL Page 2. 安装时一定要右击安装exe文件…...

中科驭数亮相DPU峰会,分享HADOS软件生态实践和大数据计算方案,再获评“匠芯技术奖”
又是一年相逢时,8月4日,第三届DPU峰会在北京开幕,本届峰会由中国通信学会指导,江苏省未来网络创新研究院主办,SDNLAB社区承办,以“智驱创新芯动未来”为主题,沿袭技术创新、生态协同的共创效应&…...
chrome、edge、Firefox关闭音量提醒控件显示
文章目录 1. Chrome2. edge3. firefox 1. Chrome 在地址栏输入: chrome://flags/#hardware-media-key-handling 将Hardware Media Key Handling的状态设为Disabled 2. edge 在地址栏输入 edge://flags/#hardware-media-key-handling 将Hardware Media Key Handling的状态…...

3.7v升压5v4A芯片用什么型号
问:我需要一个能够将3.7V锂电池的电压升压到5V,并且能够提供4A的电流输出的芯片。请问有什么推荐的型号吗? 答:小编为您推荐AH6922B芯片,它具备以下特点来满足您的需求: 1. 输入电压范围适配:…...

鉴源实验室丨SOME/IP协议安全攻击
作者 | 张昊晖 上海控安可信软件创新研究院工控网络安全组 来源 | 鉴源实验室 社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区” 01 引 言 随着汽车行业对于数据通信的需求不断增加,SOME/IP作为支持汽车以太网进程和设备间通信的一种通信协议应…...

什么?200?跨域?
情景复现 今天我遇到了一件很奇怪的事情就是,当我请求后端网关,然后通过网关去请求相应的服务,都进行了跨域处理 但是,奇怪的是我在请求的时候,回来的响应码是200,但是报错了,报的还是200的同…...

【数据结构与算法——TypeScript】算法的复杂度分析、 数组和链表的对比
【数据结构与算法——TypeScript】 算法的复杂度分析 什么是算法复杂度(现实案例)? ❤️🔥 前面已经解释了什么是算法? 其实就是解决问题的一系列步骤操作、逻辑。 ✅ 对于同一个问题,我们往往有很多种解决思路和方法&#x…...

搜索综合训练
搜索综合训练 选数详细注释的代码 小木棍详细注释的代码 费解的开关详细注释的代码 选数 详细注释的代码 #include <iostream> #include <vector>using namespace std;// 判断一个数是否为素数 bool isPrime(int num) {if (num < 1)return false;// 判断从2到s…...
snowboy+新一代kaldi(k2-fsa)sherpa-onnx实现离线语音识别【语音助手】
背景 本系列主要目标初步完成一款智能音箱的基础功能,包括语音唤醒、语音识别(语音转文字)、处理用户请求(比如查天气等,主要通过rasa自己定义意图实现)、语音合成(文字转语音)功能。 语音识别、语音合成采用离线方式实现。 语…...

APT80DQ20BG-ASEMI快恢复二极管80A 200V
编辑:ll APT80DQ20BG-ASEMI快恢复二极管80A 200V 型号:APT80DQ20BG 品牌:ASEMI 芯片个数:双芯片 封装:TO-3P 恢复时间:≤50ns 工作温度:-55C~150C 浪涌电流:600A*2 正向电流…...

Go的任务调度单元与并发编程
摘要:本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 本文主要介绍Go语言、进程、线程、协程的出现背景原因以及Go 语言如何解决协程的…...
PDFbox教程_编程入门自学教程_菜鸟教程-免费教程分享
教程简介 PDFBox是一个开源Java库,支持PDF文档的开发和转换.使用此库,您可以开发用于创建,转换和操作PDF文档的Java程序.除此之外,PDFBox还包括一个命令行实用程序,用于使用可用的PDF对PDF执行各种操作Jar文件. PDFB…...
Node.js-模块化理解及基本使用
模块化的定义 讲一个复杂的程序文件按照一定的规则拆分成多个独立的小文件,这些小文件就是小模块,这就是模块化。 每个小模块内部的数据是私有的,可以暴露内部数据给外部其他模块使用。 模块化优点 减少命名的冲突提高复用性提高可维护性按需…...
arguments 和 剩余参数
加油 !! 💕 文章目录 前言一、arguments二、arguments转成array三、箭头函数不绑定arguments四、剩余参数 ... 前言 其实在es6之后不推荐使用 arguments , 建议使用剩余参数 一、arguments arguments 是一个 对应于 传递给函数的参数 的 类数…...
【BASH】回顾与知识点梳理(十二)
【BASH】回顾与知识点梳理 十二 十二. Linux 文件与目录管理12.1 目录与路径相对路径与绝对路径相对路径的用途绝对路径的用途 12.2 目录的相关操作cd (change directory, 变换目录)pwd (Print Working Directory, 显示目前所在的目录)mkdir (make directory, 建立新目录)rmdir…...

本地构建包含java和maven的镜像
目录 1.前提条件 2.下载 2.1.创建Dockerfile 3.构建镜像 参考文章 1.前提条件 本地环境需要的系统和软件 win10 Docker Desktop Powershell 图1 Win10安装Docker后,直接在Powershell使用Docker命令 有些Developer不习惯win10系统,却想要使用Lin…...
Programming abstractions in C阅读笔记:p76-p83
《Programming Abstractions In C》学习第42天,p76-p73总结。 一、技术总结 1.数组和指针 在C语言中,数组和指针非常相似,相似到必须将它们同时考虑,当看到数组就应该想到指针,当看到指针就应该想到数组。示例…...
已解决(三个问题)|neo4j Failed authentication attempt for ‘meter‘ from 127.0.0.1
问题1 py2neo.errors.ConnectionUnavailable: Connection has been closed 问题2 neo4j Failed authentication attempt for ‘meter’ from 127.0.0.1 问题3 py2neo.errors,ClientError: [Security.Unauthorized] Invalid username or password. 作者:xiao黄 博客地址:http…...
neo4j查询语言Cypher详解(二)--Pattern和类型
Patterns 图形模式匹配是Cypher的核心。它是一种用于通过应用声明性模式从图中导航、描述和提取数据的机制。在MATCH子句中,可以使用图模式定义要搜索的数据和要返回的数据。图模式匹配也可以在不使用MATCH子句的情况下在EXISTS、COUNT和COLLECT子查询中使用。 图…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...