Redis 之四:Redis 事务和乐观锁
事务特点
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
-
批量操作在发送 EXEC 命令前被放入队列缓存。
-
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。不具备原子性。
-
在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
Redis 事务的缺点
- 不支持回滚: Redis事务在执行
EXEC命令之前,如果通过WATCH检测到监视的键发生了变化,则会拒绝执行整个事务并返回空结果。但请注意,这并不是传统数据库中的“回滚”操作,因为Redis不会自动撤销已经执行过的命令,它仅仅是在事务中止时阻止后续未执行的命令。 - 命令排队一次性执行: 在Redis事务中,所有命令会被放入一个队列,在
EXEC命令被执行时按照先进先出的顺序执行,期间不能中断或插入新的命令。这意味着事务开始后无法根据中间结果动态调整事务内的操作,降低了灵活性。 - 无隔离级别: Redis的事务没有提供如SQL数据库那样的多种事务隔离级别(如读已提交、可重复读等)。所有事务都是在单线程环境下的串行化执行,因此避免了脏读、不可重复读等问题,但这也意味着在高并发场景下可能会有性能瓶颈。
- Watch-Multi-Exec模式的问题: 使用
WATCH进行乐观锁控制时,一旦网络延迟或者客户端异常导致事务未能及时执行,监视的数据可能已经被其他客户端修改,此时即便事务最终执行,也无法保证数据一致性。 - 批量操作不具备完全的原子性: 虽然Redis的所有命令在服务器内部是原子执行的,但在一个事务中多个命令的组合并不能视为一个原子操作。例如,事务中包含对多个key的操作,即使其中一个操作失败,事务内其它命令也会被执行完毕,而不是整体取消。
三个阶段
一个事务从开始到执行会经历以下三个阶段:
- 开始事务。
- 命令入队。
- 执行事务。
案例步骤
从multi 开始,一系列操作,最后执行 exec ,批量执行处理
127.0.0.1:6379> multi
OK
127.0.0.1:6379> keys *
QUEUED
127.0.0.1:6379> hset person name zhang age 34
QUEUED
127.0.0.1:6379> hdel person age
QUEUED
127.0.0.1:6379> hset person email zhang@sina.com
QUEUED
127.0.0.1:6379> exec
1) 1) "listz"2) "book"3) "word"4) "myset"5) "mydest"6) "student"
2) (integer) 2
3) (integer) 1
4) (integer) 1
127.0.0.1:6379> hgetall person
1) "name"
2) "zhang"
下表列出了 redis 事务的相关命令:
| 序号 | 命令及描述 |
|---|---|
| 1 | [DISCARD] 取消事务,放弃执行事务块内的所有命令。 |
| 2 | [EXEC] 执行所有事务块内的命令。 |
| 3 | [MULTI] 标记一个事务块的开始。 |
| 4 | [UNWATCH] 取消 WATCH 命令对所有 key 的监视。 |
| 5 | [WATCH key [key ...]] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
乐观锁
乐观锁(Optimistic Locking)是一种在数据库并发控制中的策略,它假设多用户同时访问同一数据时发生冲突的概率较低,并且在更新数据之前并不立即进行加锁操作。与悲观锁不同的是,悲观锁在读取数据时就直接获取并持有锁,直到事务结束才释放;而乐观锁则是:
- 读取阶段:当一个事务想要修改数据时,它不会立即锁定该数据行。每个事务在读取数据时都会记录下当时的数据版本号或时间戳等信息。
- 验证阶段:在事务提交更新操作前,会再次检查当前要更新的数据是否自上次读取以来没有被其他事务修改过。这通常通过比较数据的版本号来实现,如果版本号未变,则认为可以安全地执行更新。
- 更新阶段:如果数据版本验证通过(即版本号仍为事务开始读取时的版本),则执行更新操作,并将数据版本号递增,确保后续的并发事务能够识别出这次更新。如果发现版本号已被改变,说明存在并发修改,此时乐观锁机制会让当前事务回滚,并提示并发错误,通常需要重新读取数据并尝试更新。
Redis 乐观锁
Redis 乐观锁是一种在分布式系统中实现并发控制的机制,它借鉴了数据库领域的乐观并发控制思想,并通过Redis提供的命令来实现。在乐观锁策略下,假定多个客户端同时访问同一数据时,通常不会发生冲突或至少冲突的概率较低。因此,在读取数据时不立即加锁,而是在更新数据前才去检查在此期间是否有其他客户端修改过该数据。
在Redis中,乐观锁主要通过WATCH命令和事务(multi/exec)来实现:
- WATCH命令:客户端使用
WATCH命令监视一个或多个键,这些键的数据状态将被记录下来。当执行WATCH后,如果任何被监视的键在事务提交前发生了变化,则整个事务将会被打断,即不会执行EXEC命令内的操作。 - 事务处理:客户端可以将一系列命令放入事务中,使用
MULTI开始一个事务块,然后执行一系列的操作指令。最后,用EXEC命令尝试提交事务。只有在所有被WATCH的键自WATCH以来未被其他客户端改变的情况下,事务中的命令才会被执行。
举例来说:
- 客户端A对一个键进行
WATCH。 - 然后客户端A开始一个事务,并准备修改这个键的值。
- 在事务提交(
EXEC)之前,如果其他客户端改变了该键的值,那么客户端A的事务在执行EXEC时会发现数据已经被修改,从而导致事务回滚,不执行任何操作。
下面具体来举例:
主要是 watch 和 multi 两个命令配合使用,实现乐观锁
watch 监视某一个可能变化的 key。然后开启事务,一系列操作放入队列等待执行,如果在exec 执行事务之前,其他的客户端对监视的key 做了修改,则exec 执行结果为nil 。什么都不执行。
127.0.0.1:6379> watch mm #### 开始监视 mm 变量
OK
127.0.0.1:6379> multi #### 开启事务
OK
127.0.0.1:6379> incrby mm 500 #### 第一次 给 mm 加500 操作放入队列
QUEUED
127.0.0.1:6379> incrby mm 500 #### 第二次 给 mm 加500 操作放入队列
QUEUED
### 此时去另一个客户端执行修改操作
另一个客户端的修改操作
127.0.0.1:6379> decrby mm 500 #### 给 mm 减去500
(integer) -500 #### 立即起效,结果为 -500
然后再回原来执行事务的客户端执行下面操作:
127.0.0.1:6379> exec #### 开始执行事务
(nil) #### 没有任何执行结果 因为乐观锁起作用了
127.0.0.1:6379> get mm #### 再次查看结果
"-500" #### 是另一个客户端的执行结果。刚才加的两次500 无效。
127.0.0.1:6379> watch mm #### 再次监控
OK
127.0.0.1:6379> multi #### 开启事务
OK
127.0.0.1:6379> incrby mm 500 #### 加500
QUEUED
127.0.0.1:6379> incrby mm 500 #### 加500
QUEUED
127.0.0.1:6379> exec #### 执行事务
1) (integer) 0
2) (integer) 500 #### 执行成功,因为其他客户端没有修改被监视的变量 mm .
127.0.0.1:6379> 相关文章:
Redis 之四:Redis 事务和乐观锁
事务特点 Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证: 批量操作在发送 EXEC 命令前被放入队列缓存。 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。不具备原子性。 在事务执…...
C# WPF编程-创建项目
1.创建新项目 选择“WPF应用程序”》“下一步” 设置项目 设置项目名称,保存位置等参数>下一步 3.选择框架 4.项目创建成功 5.运行项目...
密码学及其应用(应用篇15)——0/1背包问题
1 问题背景 背包问题是一个经典的优化问题,在计算机科学和运筹学中有着广泛的应用。具体到你提到的这个问题,它是背包问题中的一个特例,通常被称为0/1背包问题。这里,我们有一系列的正整数 ,以及一个正整数,…...
基于springboot+vue的实验室管理系统(前后端分离)
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 主要内容:毕业设计(Javaweb项目|小程序|Pyt…...
华为OD技术面试案例5-2024年
背景 985本计算机专业,目标院校。 1.15 投递 在某BOSS上投递的简历,HR人很nice,非常负责任。 1.19 收到机试通知 第一题是一个哈夫曼编码,第三题是一个动态规划,机试整体难度不算高,刷leetcode hot100…...
【QT+QGIS跨平台编译】之五十五:【QGIS_CORE跨平台编译】—【qgsmeshcalcparser.cpp生成】
文章目录 一、Bison二、生成来源三、构建过程一、Bison GNU Bison 是一个通用的解析器生成器,它可以将注释的无上下文语法转换为使用 LALR (1) 解析表的确定性 LR 或广义 LR (GLR) 解析器。Bison 还可以生成 IELR (1) 或规范 LR (1) 解析表。一旦您熟练使用 Bison,您可以使用…...
Unity(第二十部)效果 粒子、线条和拖尾
1、粒子系统 粒子系统介绍 Unity 粒子系统是 Unity 引擎中用于创建和控制粒子效果的工具。它可以模拟各种自然现象,如火焰、烟雾、雨滴等,也可以用于创建特效,如魔法光芒、爆炸效果等。 粒子系统组成 在 Unity 中,粒子系统由发射…...
全量知识系统问题及SmartChat给出的答复 之6 三套工具之1
Q15. 提出想法和问题 前面说过,DDD在我要设计的全量知识系统中位于中间层,是专门用来解决“知识汤”问题的。 解决的思路就是以将为在特定领域中的公司经营提供一个责任-权限平面为目的,帮助他们调整商业模式以及组建恰当的组织,…...
[RoarCTF 2019]Easy Calc
这题考查的是: 字符串解析特性目录读取文件内容读取 字符串解析特性详解:PHP字符串解析特性 ($GET/$POST参数绕过)(含例题 buuctf easycalc)_参数解析 绕过-CSDN博客 ascii码查询表:ASCII 表 | 菜鸟工具 …...
完美解决 git 报错fatal: Not a git repository (or any of the parent directories): .git
问题描述 错误提示是找不到.git文件,无法执行git指令,意思是 当前你要提交的文件夹中没有.git这个文件 解决方案 执行如下命令: git init...
electron无法设置自己的图标?渲染进程require报错?
electron无法设置自己的图标? 极有可能是图标太大,或者宽高不同 我推荐的网址icon转换 选着20x20一般就可以 渲染进程无法使用require?一直报错? webPreferences: {nodeIntegration: true, enableRemoteModule: true, contextIsolation: …...
vscode连接服务器与FileZilla上传到服务器
https://www.cnblogs.com/qiuhlee/p/17729647.html(这个是vscode连接服务器) 主机:就是服务器的主机号 使用者名称:比如ALmax的用户名 密码:比如ALmax的密码...
练习 1 Web EasySQL极客大挑战
CTF Week 1 EasySQL极客大挑战 BUUCTF 典中典复习 Web SQL 先尝试输入,找一找交互页面 check.php 尝试万能语句 a’ or true SQL注入:#和–的作用 get传参只能是url编码,注意修改编码,输入的字符串要改成url格式。 POST请求和…...
matlab生成模拟的通信信号
matlab中rand函数生成均匀随机分布的随机数,randn生成正态分布的随机数; matlab来模拟一个通信信号; 通信信号通过信道时,研究时认为它会被叠加上服从正态分布的噪声; 先生成随机信号模拟要传输的信号,s…...
Altair® SimLab® 以流程为导向的多学科仿真环境,可连接CAD 的多物理场工作流程
Altair SimLab 以流程为导向的多学科仿真环境,可连接CAD 的多物理场工作流程 SimLab 是一种以流程为导向的多学科仿真环境,能够精确分析复杂装配体的性能表现。包括结构、热和流体动力学在内的多物理场可以通过高度自动化的建模任务轻松设置,有助于大幅…...
Python爬虫-爬取B站番剧封面
本文是本人最近学习Python爬虫所做的小练习。如有侵权,请联系删除。 页面获取url 代码 import requests import os import re# 创建文件夹 path os.getcwd() /images if not os.path.exists(path):os.mkdir(path)# 当前页数 page 1 # 总页数 total_page 2# 自动…...
AI时代的产品文案秘籍:如何用AI提升效率
人工智能写作工具:解放双手,创作不停歇 在当前人工智能技术飞速发展的背景下,越来越多的个体已经开始利用这一AI写作工具,以显著提高自己的工作效率。这不仅标志着人工智能服务于人类的宏伟时代的到来,更是人人可用的创…...
前端架构: 脚手架通用框架封装之入口文件开发(教程一)
脚手架入口文件开发 创建脚手架项目: abc-cli $ mkdir abc-cli && cd abc-cli 全局安装 lerna, $ npm i -g lerna 基于 lerna 完成项目初始化 $ lerna init 基于 lerna 创建脚手架 cli $ lerna create cli一路回车 好现在生成了一个 cli 的模板,目前需要…...
吴恩达《机器学习》学习笔记
本笔记资料来源于 http://www.ai-start.com/ml2014/,该笔记来自于https://blog.csdn.net/dadapongi6/article/details/105668394,看了忘,忘了看,再看一遍。 时间统计:2024.2.29 5个番茄钟,从week1开始&…...
【FPGA】线性反馈移位寄存器(LFSR)的Verilog实现
什么是移位寄存器 移位寄存器:是指多个寄存器并排相连,前一个寄存器的输出作为下一个寄存器的输入,寄存器中存放的数据在每个时钟周期向左或向右移动一位。 下面的右移移位寄存器因为左侧没有有效输入,所以在第4个时钟周期&…...
第17届蓝桥杯C语言B组省赛题目
2026年4月11日#include <stdio.h>int main() {long long N 2026202520242023;long long ans 0;for (long long i 0; i < 1013101260121012; i){if (N-i > i){ans;}else{return 0;}}printf("%lld", ans);return 0; }#include <stdio.h>long long…...
保姆级拆解:NCCL路径计算如何影响你的多GPU训练性能(附排查脚本)
深度解析NCCL路径计算对多GPU训练性能的影响与优化实践 当你在8卡服务器上运行PyTorch DDP训练时,是否遇到过GPU3的利用率始终比其它卡低30%的情况?或者在使用DeepSpeed进行多节点训练时,发现跨节点通信耗时占据了整个迭代时间的40%以上&…...
WorkshopDL:免费下载Steam创意工坊模组的终极完整指南 [特殊字符]
WorkshopDL:免费下载Steam创意工坊模组的终极完整指南 🎮 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 还在为无法访问Steam创意工坊的丰富模组资源而…...
EPLAN拖放操作避坑指南:从符号宏到DWG导入,这些细节错了白忙活
EPLAN拖放操作避坑指南:从符号宏到DWG导入,这些细节错了白忙活 刚接触EPLAN的工程师们,往往会被它强大的拖放功能吸引——毕竟谁不喜欢这种直观高效的操作方式呢?但当你兴冲冲地尝试把DWG文件拖进项目时,却发现系统毫无…...
踩坑实战分享如何在 IntelliJ IDEA 中创建一个包含 JSP 和 Servlet6.0 的 Maven Web 项目,并配置 Tomcat 进行调试
在现代 Java Web 开发体系中,虽然 Spring Boot 早已成为主流,但 JSP Servlet 依然是理解 Web 容器原理、请求响应机制、MVC 分层思想的重要基础。对于初学者来说,能够在 IntelliJ IDEA 中从零创建一个包含 JSP 和 Servlet 6.0 的 Maven Web …...
别再手动调RTL了!用Verilog高级综合给AI加速器‘瘦身’,功耗直降30%的实战复盘
从RTL到HLS:一个AI加速器模块的功耗优化实战手记 去年夏天,我们的AI芯片团队遇到了一个棘手的问题——手工编写的RTL代码在28nm工艺下功耗超标23%。当项目进度已经滞后两个月时,我们决定尝试用Verilog高级综合(HLS)重构卷积加速模块。没想到这…...
关系型数据库MySQL(一):数据库基础
MySQL数据库基础教程一、 数据库基础概念什么是数据库 (Database, DB)?简单来说,数据库就是一个有组织、可持久化存储的数据集合。你可以把它想象成一个电子化的文件柜,里面存放着大量结构化的信息。数据库管理系统 (Database Management System, DBMS)…...
**发散创新:基于Python与ROS的自主移动机器人路径规划实战**
发散创新:基于Python与ROS的自主移动机器人路径规划实战 在智能硬件与人工智能深度融合的今天,自主系统正逐步从实验室走向现实场景。本文聚焦于Python语言 ROS(Robot Operating System)框架构建一个具备环境感知与动态避障能力的…...
深度解析:如何实现游戏性能400%突破性提升的技术秘籍
深度解析:如何实现游戏性能400%突破性提升的技术秘籍 【免费下载链接】Performance-Fish Performance Mod for RimWorld 项目地址: https://gitcode.com/gh_mirrors/pe/Performance-Fish Performance-Fish是一款专为《环世界》(RimWorldÿ…...
别再死记硬背了!一张图搞定华为数通里的网络类型与拓扑(附实战场景联想)
华为数通实战指南:网络类型与拓扑的图形化记忆法 刚接触华为数通认证的学习者,常被各种网络类型和拓扑结构搞得晕头转向。LAN、MAN、WAN这些概念看似简单,但一到实际应用场景就容易混淆;星型、网状、树形等拓扑结构虽然能背下来&a…...
