当前位置: 首页 > news >正文

Redis中的事务机制

Redis中的事务机制

概述。

事务表示一组动作,要么全部执行,要么全部不执行。例子如下。
Redis提供了简单的事务功能,讲一组需要一起执行的命令放到multi和exec两个命令之间。multi命令代表事务开始,exec命令代表事务结束,如果要停止事务的执行,可以使用discard命令代替exec命令即可。它们之间的命令是原子执行的

例子

例如在社交网站上用户A关注了用户B,那么需要在用户A的关注表中加入用户B,并且在用户B的粉丝表中添加用户A,这两个行为要么全部执行,要么全部不执行,否则会出现数据不一致的情况

例如下面代码实现了用户关注问题

127.0.0.1:6379> SADD u:a:follow ub
QUEUED
127.0.0.1:6379> SADD u:b:fans ua
QUEUED

可以看到SADD命令此时的返回结果是QUEUED,代表命令并没有真正执行,而是暂时保存在Redis中的一个缓存队列(所以discard也只是丢弃这个缓存队列中的未执行命令,并不会回滚已经操作过的数据,这一点要和关系型数据库的Rollback操作区分开)。如果此时另一个客户端执行下方代码,返回结果应该是0

127.0.0.1:6379> SISMEMBER u:a:follow ub
(integer) 0

只有当exec执行后,用户A关注用户B的行为才算完成,如下所示exec返回的两个结果对应SADD命令

127.0.0.1:6379> multi
OK
127.0.0.1:6379> SADD u:a:follow ub
QUEUED
127.0.0.1:6379> SADD u:b:fans ua
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 1

另一个客户端:

127.0.0.1:6379> SISMEMBER u:a:follow ub
(integer) 0
127.0.0.1:6379> SISMEMBER u:a:follow ub
(integer) 1

错误处理机制

如果事务中的命令出现错误,Redis的处理机制也不尽相同

1.命令错误

例如下面操作将set写成了SETT,属于语法错误,会造成整个事务无法执行,

127.0.0.1:6379> set txkey hello
OK
127.0.0.1:6379> set txcount 100
OK
127.0.0.1:6379> mget txkey txcount
1) "hello"
2) "100"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> sett txkey world
(error) ERR unknown command `sett`, with args beginning with: `txkey`, `world`,
127.0.0.1:6379> incr txcount
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> mget txkey txcount
1) "hello"
2) "100"

2.运行时错误

例如用户B在添加粉丝列表时,误把SADD命令(针对集合)写成了ZADD命令(针对有序集合),这种就是运行时命令,因为语法时正确的:

127.0.0.1:6379> SADD u:b:fans ua
(integer) 1
127.0.0.1:6379> multi
OK
127.0.0.1:6379> SADD u:c:follow ub
QUEUED
127.0.0.1:6379> ZADD u:b:fans 1 uc
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> sismember u:c:follow ub
(integer) 1

可以看到Redis并不支持回滚功能,SADD u:c:follow ub命令已经执行成功,开发人员需要自己修复这类问题。

3.WATCH机制

有些应用场景需要在事务之前,确保事务中的key没有key没有被其他客户端修改过,才执行事务,否则不执行(类似乐观锁)。Redis提供了watch命令来解决这类问题。
客户端1

127.0.0.1:6379> set testwatch java
OK
127.0.0.1:6379> watch testwatch
OK
127.0.0.1:6379> multi
OK

客户端2

127.0.0.1:6379> get testwatch
"java"
127.0.0.1:6379> append testwatch python
(integer) 10

客户端1继续:

127.0.0.1:6379> append testwatch jedis
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get testwatch
"javapython"

可以看到客户端1在执行multi之前执行了watch命令,客户端2在客户端1执行exec之前修改了key值,造成可客户端1事务没有执行(exec结果为nil)

Pipeline和事务的区别

  • 1.pipeline是客户端的行为,对于服务器来说是透明的,可以认为服务器无法区分客户端发送来的查询命令是以普通命令的形式还是以pipeline的形式发送到服务器的;
  • 2.而事务则是实现在服务器端的行为,用户执行MULTI命令时,服务器会将对应这个用户的客户端对象设置为一个特殊的状态,在这个状态下后续用户执行管的查询命令不会被真的执行,而是被服务器缓存起来,直到用户执行EXEC命令为止,服务器会将这个用户对应的客户端对象中缓存的命令按照提交的顺序依次执行
  • 3.应用pipeline可以提高服务器的吞吐能力,并提高Redis处理查询请求的能力。但是这里存在一个问题,当通过pipeline提交的查询命令数据较少,可以被内核缓冲区所容纳时,Redis可以保证这些命令执行的原子性。然而一旦数据量过大,超过了内核缓冲区的接收大小,那么命令的执行将会被打断,原子性也就无法得到保证。因此pipeline只是一种提升服务器吞吐能力的机制,如果想要命令以事务的方式原子性地被执行,还是需要事务机制,或者使用更高级的脚本功能以及模块功能
  • 4.可以将事务和pipeline结合起来使用,减少事务地命令在网络上的传输时间,将多次网络IO缩减为一次网络IO.
  • Redis提供了简单的事务,之所以说它简单,主要时因为它不支持事务中的回滚特性,同时无法实现命令之间的逻辑关系计算,当然也体现了Redis的"keep it simple"的特性

Lua脚本

Redis在2.6推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行,使用脚本的好处如下:

  • 1.减少网络开销:本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在Redis服务器上完成,使用脚本,减少了网络往返时延,跟管道类似
  • 2.源自操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入,管道不是原子的,redis的批量操作命令(类似mset)是原子的
  • 3.替代redis的事务功能:redis自带的事务功能很鸡肋,而redis的lua脚本几乎实现了常规的事务功能,官方推荐如果要使用redis的事务功能可以用redis lua替代
    A Redis script is transactional by definition, so everything you can do with a Redis transaction, you can also do with a script,and usually the script will be both simpler and faster.

相关文章:

Redis中的事务机制

Redis中的事务机制 概述。 事务表示一组动作,要么全部执行,要么全部不执行。例子如下。 Redis提供了简单的事务功能,讲一组需要一起执行的命令放到multi和exec两个命令之间。multi命令代表事务开始,exec命令代表事务结束&#x…...

从零到一构建短链接系统(八)

1.git上传远程仓库(现在才想起来) git init git add . git commit -m "first commit" git remote add origin OLiyscxm/shortlink git push -u origin "master" 2.开发全局异常拦截器之后就可以简化UserController 拦截器可以…...

缺省和重载。引用——初识c++

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 C输入&输出cout 和cin<<>> 缺省参数全缺省半缺省应用场景声明和定义分离的情况 函数重载1.参数的类型不同2.参数的个数不同3.参数的顺…...

java常用IO流功能——字符流和缓冲流概述

前言&#xff1a; 整理下学习笔记&#xff0c;打好基础&#xff0c;daydayup! 之前说了下了IO流的概念&#xff0c;并整理了字节流&#xff0c;有需要的可以看这篇 java常用应用程序编程接口&#xff08;API&#xff09;——IO流概述及字节流的使用 字符流 FileReader(文件字…...

Python中模块的定义、用法

在Python中&#xff0c;模块是一个包含了Python代码的文件。模块可以包含变量定义、函数、类等&#xff0c;并且可以在其他Python脚本中被导入和使用。模块的定义和用法如下所示&#xff1a; 模块的定义&#xff1a; 创建模块文件&#xff1a;在Python中&#xff0c;一个模块就…...

【vscode 常用扩展插件】

vscode 常用扩展插件 常用插件部分插件使用技巧1、eslint 保存自动格式化2、代码片段的使用3、最后是关于引入文件路径提示的 常用插件 记录vscode方便开发的扩展插件&#xff0c;方便换电脑时&#xff0c;快速部署所需环境。 部分插件 1、Auto Close Tag html自动闭合标签插…...

Retelling|Facebook2

录音 Facebook 2 Retelling|Facebook2 复述转写 Hi, Im Helen Campbell, from DJ interpretation, European Commission, Im going to talk about Facebook. You Im sure that you are more familiar with Facebook, a lot, a lot more familiar than I than me. But Ive read…...

读3dsr代码①测试

前置任务 首先是作者不公开checkpoints&#xff0c;需要自己训练一遍 这里先不载入模型单纯过一遍流程 而且因为没有说明是否需要去背景&#xff08;之后再过一下论文&#xff09;&#xff0c;所以反正先用去过背景的数据debug一下 3DSR/geo_utils.py:61: RuntimeWarning: inv…...

Vant Weapp小程序 van-uploader 文件上传点击无反应,删除无反应

Vant Weapp 1.0 版本开始支持van-uploader组件&#xff0c;请先确认好版本号和引用路径正确&#xff01;&#xff01; <van-uploader file-list"{{ fileList }}" deletable"{{ true }}" />1. 上传无反应 微信小程序用了van-uploader&#xff0c;但是…...

【力扣】55.跳跃游戏、45.跳跃游戏Ⅱ

55.跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&a…...

038—pandas 重采样线性插补

前言 在数据处理时&#xff0c;由于采集数据量有限&#xff0c;或者采集数据粒度过小&#xff0c;经常需要对数据重采样。在本例中&#xff0c;我们将实现一个类型超分辨率的操作。 思路&#xff1a; 首先将原始数据长度扩展为 3 倍&#xff0c;可以使用 loc[] 方法对索引扩…...

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示(PC端、手机端、平板端)

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示&#xff08;PC端、手机端、平板端&#xff09; 智慧工地系统多端展示&#xff08;PC端、手机端、平板端&#xff09;;数字孪生可视化大屏&#xff0c;一张图掌握项目整体情况;使用轻量化模型&#xff0c;部署三…...

深度学习Top10算法之深度神经网络DNN

深度神经网络&#xff08;Deep Neural Networks&#xff0c;DNN&#xff09;是人工神经网络&#xff08;Artificial Neural Networks&#xff0c;ANN&#xff09;的一种扩展。它们通过模仿人脑的工作原理来处理数据和创建模式&#xff0c;广泛应用于图像识别、语音识别、自然语…...

【智能算法】海马优化算法(SHO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2022年&#xff0c;Zhao等人受到海马自然社会行为启发&#xff0c;提出了海马优化算法&#xff08;Sea-horse Optimizer, SHO&#xff09;。 2.算法原理 2.1算法思想 SHO模拟了海马群在自然界中的…...

AI大模型学习的伦理与社会影响

AI大模型学习 随着人工智能技术的快速发展&#xff0c;AI大模型学习成为当前热门研究领域之一。AI大模型学习是指基于大规模数据集和深度学习模型进行训练&#xff0c;以实现更高的准确性和复杂性。这些大模型已经在几乎所有领域都取得了显著的成就&#xff0c;包括自然语言处…...

记录些LangChain相关的知识

RAG的输出准确率 RAG的输出准确率 向量信息保留率 * 语义搜索准确率 * LLM准确率RAG的输出准确率由三个因素共同决定&#xff1a;向量信息保留率、语义搜索准确率以及LLM准确率。这三个因素是依次作用的&#xff0c;因此准确率实际上是它们的乘积。这意味着&#xff0c;任何一…...

C语言例4-7:格式字符f的使用例子

%f&#xff0c;实型&#xff0c;小数部分为6位 代码如下&#xff1a; //格式字符f的使用例子 #include<stdio.h> int main(void) {float f 123.456;double d1, d2;d11111111111111.111111111;d22222222222222.222222222;printf("%f,%12f,%12.2f,%-12.2f,%.2f\n&qu…...

[蓝桥杯 2019 省 A] 修改数组

题目链接 [蓝桥杯 2019 省 A] 修改数组 题目描述 给定一个长度为 N N N 的数组 A [ A 1 , A 2 , A 3 , . . . , A N ] A [A_1, A_2, A_3, ...,A_N] A[A1​,A2​,A3​,...,AN​]&#xff0c;数组中有可能有重复出现的整数。 现在小明要按以下方法将其修改为没有重复整数的…...

Git基础(25):Cherry Pick合并指定commit id的提交

文章目录 前言指定commit id合并使用TortoiseGit执行cherry-pick命令 前言 开发中&#xff0c;我们会存在多个分支开发的情况&#xff0c;比如dev&#xff0c;test, prod分支&#xff0c;dev分支在开发新功能&#xff0c;prod作为生产分支已发布。如果某个时候&#xff0c;我们…...

C语言结构体之位段

位段&#xff08;节约内存&#xff09;&#xff0c;和王者段位联想记忆 位段是为了节约内存的。刚好和结构体相反。 那么什么是位段呢&#xff1f;我们现引入情景&#xff1a;我么如果要记录一个人是男是女&#xff0c;用数字0 1表示。我们发现只要一个bit内存就可以完成我们想…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...