redis事务管理详解
事务管理
- 事务管理
- 乐观锁与悲观锁
- watch命令实现乐观锁
- watch命令示例
事务管理
Redis 提供了事务管理功能,可以通过 Redis 的 MULTI、EXEC、WATCH 和 DISCARD 命令来实现。
-
开启事务:
使用 MULTI 命令开始一个事务,表示接下来执行的命令都属于该事务。示例:
MULTI
-
执行事务操作:
在事务中可以执行多个命令,这些命令不会立即执行,而是被放入一个队列中。示例:
SET key1 value1 GET key1 INCR key2
-
提交事务:
使用 EXEC 命令提交事务,Redis 会按照命令的顺序执行队列中的所有命令。示例:
EXEC
执行 EXEC 命令后,Redis 会执行对应的事务命令,并返回每个命令的执行结果。
-
监视键变化:
可以使用 WATCH 命令监视一个或多个键的变化。如果在事务执行期间,被监视的键发生了修改,事务将被中止。示例:
WATCH key1 key2
-
取消事务:
如果在执行事务前需要取消当前事务,可以使用 DISCARD 命令。示例:
DISCARD
事务的特性:
- Redis 事务是一单个隔离的操作序列,从开始到提交期间,Redis 不会中断该序列,也不会处理其他客户端的请求。
- 在 EXEC 命令前,事务中的命令都只是进入队列,并没有实际执行,所以即使其中某个命令出错,也不会影响其他命令的执行。
- Redis 并不提供回滚机制,一旦事务提交,其中的命令就会全部执行,无法撤销。
- 如果在 WATCH 监视的键被修改后,EXEC 命令执行前,事务会被放弃执行。
需要注意的是,Redis 的事务并不具备像关系型数据库那样的 ACID 特性。它主要用于将多个命令打包在一起,确保这些命令的原子性执行,但事务间没有隔离性和持久性的特性。
乐观锁与悲观锁
Redis中的乐观锁和悲观锁是用于处理并发访问时保证数据一致性的两种不同策略。
-
乐观锁:
- 实现方式:乐观锁是基于数据版本号或者时间戳来实现的。在读取数据之前,会获取该数据的版本号或时间戳,然后在更新数据时比对版本号或时间戳,如果匹配则更新成功,否则表示其他客户端已经修改了数据。
- 实际操作:在Redis中,
使用WATCH命令监视指定的键
之后使用MULTI/EXEC组合多个命令进行操作,如果在执行期间监视的键被其他客户端修改过,则事务将中止执行。 - 应用场景:适用于读操作较多、写冲突较少的场景。
-
悲观锁:
- 实现方式:悲观锁是基于锁机制实现的,即在访问数据之前,就直接加锁,确保在当前事务完成之前其他事务无法访问相同的数据。
- 实际操作:在Redis中,可以使用SET命令
设置带有NX
(不存在则创建)参数的锁键,如果设置成功则表示获得锁,操作完成后再释放锁。 - 应用场景:适用于写操作较多、写冲突较多的场景。
需要根据具体情况选择合适的锁策略。乐观锁在遇到并发冲突时不会阻塞等待,而是通过检测来解决并发问题;悲观锁则会直接加锁,可能会导致其他事务等待,但可以确保数据的一致性。
watch命令实现乐观锁
Redis中的WATCH命令用于实现乐观锁。它可以监视一个或多个键,并在执行事务期间检查这些键是否被修改,如果被修改则中止事务的执行。
使用WATCH命令的步骤如下:
- 使用MULTI命令开启事务。
- 使用WATCH命令监视需要检查的键。
- 执行一系列的读操作,获取需要修改的数据。
- 如果
其他客户端修改了被监视的键
,则事务将中止
执行。 - 如果键未被修改,继续执行事务中的其他命令。
- 使用EXEC命令提交事务。
示例代码如下:
WATCH key1 key2 ...
MULTI
// 在事务中执行读取、修改等操作
EXEC
当执行EXEC命令时,Redis会检查被WATCH命令监视的键是否被其他客户端修改过,如果有修改,则事务将中止执行,返回空结果。否则,事务将按照顺序执行其中的命令。
WATCH命令可以通过在客户端代码中嵌入实现乐观锁的逻辑,以确保在并发环境下对数据的修改是同步和一致的。
watch命令示例
示例:当使用Redis的WATCH命令进行乐观锁处理时,可以通过两个事务来说明其工作原理。
假设有两个客户端同时
对同一个键进行操作,其中一个客户端执行了事务A,另一个客户端执行了事务B。
事务A的代码示例:
WATCH key
MULTI
SET key "New Value"
EXEC
事务B的代码示例:
WATCH key
MULTI
SET key "Another Value"
EXEC
两个事务的执行都失败
下面是执行过程的解释:
- 初始状态:假设"key"的值为"Initial Value"。
- 事务A开始执行:
- 使用WATCH命令监视"key"。
- 执行事务A中的命令。
- 尝试将"key"的值设置为"New Value"。
- 如果在执行期间没有其他客户端修改了"key",则提交事务A,“key"的值更新为"New Value”。
- 如果在执行期间有其他客户端修改了"key",则事务A被中止,不会修改"key"的值。
- 事务B开始执行:
- 使用WATCH命令监视"key"。
- 执行事务B中的命令。
- 尝试将"key"的值设置为"Another Value"。
- 如果在执行期间没有其他客户端修改了"key",则提交事务B,“key"的值更新为"Another Value”。
- 如果在执行期间有其他客户端修改了"key",则事务B被中止,不会修改"key"的值。
通过使用WATCH命令,事务A和事务B在执行期间都会监视"key"的变化情况。如果有其他客户端对"key"进行修改,则当前事务将被中止,从而保证数据的一致性和并发操作的正确性。
相关文章:
redis事务管理详解
事务管理 事务管理乐观锁与悲观锁watch命令实现乐观锁watch命令示例 事务管理 Redis 提供了事务管理功能,可以通过 Redis 的 MULTI、EXEC、WATCH 和 DISCARD 命令来实现。 开启事务: 使用 MULTI 命令开始一个事务,表示接下来执行的命令都属于…...

国产低功耗蓝牙HS6621CxC/6621Px系列支持Find My网络功能方案芯片
目录 什么是“Find My“?HS6621系列简介 什么是“Find My“? “Find My”是苹果公司于19年前推出的针对失物追踪,Find My iPhone(查找我的iPhone)和Find My Friends(查找朋友)的结合体应用。为…...
【openGauss】分区表的介绍与使用
一、openGauss分区表介绍 在openGauss中,数据分区是在一个节点内部对数据按照用户指定的策略做进一步的水平分表,将表中的数据按照指定方式划分为多个互不重叠的部分。 对于大多数用户使用场景,分区表和普通表相比具有以下优点: …...

代码随想录算法训练营day57
文章目录 Day57回文子串题目思路代码 最长回文子序列题目思路代码 Day57 回文子串 647. 回文子串 - 力扣(LeetCode) 题目 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。…...
【基础类】—前后端通信类系统性学习
一、什么是同源策略及限制 同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。源:协议、域名和端口, 默认端口是80 三者有一个不同,即源不同,就是跨域 ht…...

vite项目中使用@代表根路径
1.配置vite.config.ts import { defineConfig } from vite import vue from vitejs/plugin-vue import path from pathexport default defineConfig({plugins: [vue()],resolve: {alias:{: path.resolve(__dirname, src) }} })2.报错path和__dirname 找不到模块“path”或其相…...

冶金化工操作VR虚拟仿真实验软件提高员工们协同作业的配合度
对于高风险行业来说,开展安全教育培训是企业的重点工作,传统培训逐渐跟不上时代变化和工人需求,冶金安全VR模拟仿真培训系统作为一种新型的教育和培训工具,借助VR虚拟现实技术为冶金行业的工人提供一个安全、高效的培训环境。 冶金…...

SQL Server数据库 -- 索引与视图
文章目录 一、索引 聚集索引非聚集索引二、视图三、自定义函数 标量函数表值函数四、游标五、总结 前言 在学习完创建库表、查询等知识点后,为了更加方便优化数据库的存储和内容,我们需要学习一系列的方法例如索引与视图等等,从而使我们更加…...

2023 java web面试秘籍
目录 第一章:Java Web基础知识1.介绍3.Java Web基本概念 4.常见面试问题第二章:Java Web核心概念和技术1.介绍3.Servlet和JSP4.Web安全5.常见面试问题 第三章:Java Web高级概念和技术1.介绍3.Spring框架4.安全性5.常见面试问题 第四章&#x…...
2023-08-05力扣今日二题
链接: 剑指 Offer 18. 删除链表的节点 题意: 如题 解: 基础链表操作 实际代码: #include<iostream> using namespace std; struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {} }; Li…...

stl_list类(使用+实现)(C++)
list 一、list-简单介绍二、list的常用接口1.常见构造2.iterator的使用3.Capacity和Element access4.Modifiers5.list的迭代器失效 三、list实现四、vector 和 list 对比五、迭代器1.迭代器的实现2.迭代器的分类(按照功能分类)3.反向迭代器(1)、包装逻辑…...

利用hfish反控境外攻击源主机
导师给了7个网络安全课题选题,本想和他聊了下思路,他一挥手让我先做出点东西再来聊就把我打发走了…… 正好前段时间阿里云到校做推广,用优惠卷薅了一台云服务器,装了hfish先看下情况 没想到才装上没两天数据库就爆了࿰…...

4、Rocketmq之存储原理
CommitLog ~ MappedFileQueue ~ MappedFile集合...

在线原型设计工具有好用的吗?就是这10个
随着设计工作的不断发展,原型设计在设计工作中越来越重要,而在线原型设计工具在减轻了设计师工作负担的同时也提高了设计师的工作效率,今天本文将为大家推荐10个能在线使用的原型设计工具,一起来看看吧! 1、即时设计 …...

Vc - Qt - QPainter translate
QPainter的translate()函数是用来对绘制坐标系统进行平移操作的方法。它可以将绘制的原点(坐标轴的起始点)在水平和垂直方向上进行平移。以下是一个使用QPainter的translate()方法进行坐标平移的示例代码: QPainter painter(this);// 绘制一个…...

Spark Catalog详解
前言 旁边的实习生说:我想要用spark代码中对hive库中的内部表和外部表进行批量删除(包括数据),咋感觉网上搜了一圈都找不到解决方案啊,spark这么鸡肋吗? 我:你应该静下心来好好把spark基础知识进行全面学习。 实习生:难道spark有这功能,而我没有学习过?咋弄啊? 我:…...

【Spring专题】手写简易Spring容器过程分析
前置知识 《【Spring专题】Spring底层核心原理解析》 思路整理 我们在上一节《【Spring专题】Spring底层核心原理解析》课里面有简单分析过一个Spring容器的一般流程,所以,本节课我们这里尝试写一下简易的Spring容器。 手写源码示例 一、手写前的准…...

fastadmin自定义键值组件Fieldlist
需求场景: 后台设置前端的固定话费充值金额。编辑时要求能够增删改,给到前端的数据,是要根据金额正序排列,用fastadmin的键值组件(Fieldlist),使用Art-Template模板语法自定义模板。 最终效果如下图所示: …...

yolov2检测网数据集标注_labelme使用_json2txt格式转换
yolov2检测网数据集标注_labelme使用_json2txt格式转换 一、安装Anaconda二、创建labelme虚拟环境三、使用labelme标注健康非健康猫狗数据3.1 打开数据集所在文件夹3.2 进行标注数据集3.3 json2txt3.4 按文件目录和训练测试数据集重分配 四、数据喂给服务器网络参考链接 一、安…...

C/C++面试总结
一、关键字static、const、extern、volatile作用 1、const 1.修饰常量 用const修饰的变量是不可变的,修饰后的变量只能使用,不能修改。 2.修饰指针 如果const位于*的左侧,eg:const int* a,则const就是用来修饰指针…...

DVWA全靶场
目录 暴破 Low - 万能密码 Medium - 转义 High - Token Impossible 命令注入 CSRF跨站请求伪造 - 抓包 Low Medium - 域名限制 High - 域名限制xss 文件包含 - 页面点点点 Low Medium - 过滤http:// High - file Impossible - 写死 文件上传 Low Medium - 文件…...

【Python 算法零基础 4.排序 ⑨ 堆排序】
目录 一、问题描述 二、算法对比 1.朴素算法 ① 数组模拟容器 ② 有序数组模拟容器 2.二叉堆 ① 二叉堆特点 ② 数组表示二叉树 ③ 堆 ④ 大顶堆 ⑤ 小顶堆 ⑥ 元素插入 ⑦ 获取堆顶 ⑧ 堆顶元素删除 三、代码分析 1.工具函数 2.调整大顶堆函数 Ⅰ、计算子节点索引 Ⅱ、找出最…...

QT常用控件(1)
控件是构成QT的基础元素,例如Qwidget也是一个控件,提供了一个‘空’的矩形,我们可以往里面添加内容和处理用户输入,例如:按钮(QpushButton),基础显示控件(Lableÿ…...
【Linux基础知识系列】第十三篇-Cron与定时任务管理
在Linux系统中,任务自动化是提高效率和确保服务连续性的关键。Cron是一个强大的定时任务管理工具,它允许用户设置定期执行的命令或脚本。通过Cron,用户可以自动化系统维护、备份、报告生成等多种任务。本文将详细介绍如何使用Cron工具创建和管…...
每日算法 -【Swift 算法】电话号码字母组合
🚀 LeetCode 字符串数字映射(Swift)——电话号码字母组合 在日常刷题或面试中,我们经常会遇到字符串 回溯组合的问题。这道经典题——电话号码的字母组合 就是典型代表。本文将带你用 Swift 实现这道题,思路清晰&…...

LHA9924芯片可代替AD7190,CS5530
LHA9924是一款高性能、单芯片模数转换器(ADC)。该器件包括一个低噪声可编程增益放大器(PGA)、Δ-Σ调制器和数字滤波器。该ADC支持两种运行模式,可在功耗与分辨率之间实现最佳平衡。双通道多路复用器可以选择外部信号测量和内部ADC测试信号。具有使输入电路短路来测…...

基于开源AI智能名片链动2+1模式S2B2C商城小程序的生态农庄留存运营策略研究
摘要:本文聚焦于生态农庄运营中的游客留存问题,以村长与乡亲们吸引游客进村为背景,深入探讨如何借助开源AI智能名片链动2 1模式S2B2C商城小程序实现游客的有效留存。通过分析该小程序在信息传递、服务整合、营销激励等方面的优势,…...

A*算法实现原理以及实现步骤(C++)
算法原理: A*算法是一种启发式搜索算法,用于在图中寻找最短路径。它结合了Dijkstra算法的确保最短路径的优点和贪心最佳优先搜索的高效性。其核心在于使用一个评估函数: f(n) g(n) h(n) 其中: - g(n) 表示从起点到节点n的实际代…...
C++11实现TCP网络通讯服务端处理逻辑简化版
以下是使用C11实现的TCP服务端处理逻辑,包含循环读取数据、帧头检测(AABBCC)及4376字节数据包处理: cpp #include <iostream>#include <vector>#include <cstring>#include <unistd.h>#include <arp…...

PARADISE:用于新生儿缺氧缺血性脑病(HIE)疾病识别与分割的个性化和区域适应性方法|文献速递-深度学习医疗AI最新文献
Title 题目 PARADISE: Personalized and regional adaptation for HIE disease identification and segmentation PARADISE:用于新生儿缺氧缺血性脑病(HIE)疾病识别与分割的个性化和区域适应性方法 1 文献速递介绍 缺氧缺血性脑病&…...