文章目录

  • 一、什么是事务?
  • 二、事务相关操作
    • 总体认识
    • 基本操作流程
    • watch 操作演示
    • watch 原理

一、什么是事务?

Redis 的事务和 MySQL 的事务概念上是类似的. 都是把⼀系列操作绑定成⼀组. 让这⼀组能够批量执⾏.
Redis 的事务和 MySQL 事务的区别:

  • 弱化的原⼦性: redis 没有 “回滚机制”. 只能做到这些操作 “批量执⾏”. 不能做到 “⼀个失败就恢复到初始状态”.
  • 不保证⼀致性: 不涉及 “约束”. 也没有回滚. MySQL 的⼀致性体现的是运⾏事务前和运⾏后结果都是合理有效的, 不会出现中间⾮法状态.
  • 不需要隔离性: 也没有隔离级别, 因为不会并发执⾏事务 (redis 单线程处理请求) .
  • 不需要持久性: 是保存在内存的. 是否开启持久化, 是redis-server ⾃⼰的事情, 和事务⽆关.

关于 Redis 事务原子性的争议
争议点主要在于 原子性 的定义到底是把命令打包一起执行即可还是在此基础上必须具备 MySQL事务的回滚机制

Redis 事务理解
Redis 事务本质上是把一系列命令插入到 “事务队列中”。每次客户端在事务中进⾏⼀个操作, 都会把命令先发给服务器, 放到 “事务队列” 中(但是并不会立即执行)。等遇到 EXEC 命令之后,才会按照队列顺序依次执行命令。

Redis 事务的使用场景
秒杀(抢票)

在抢票场景中需要注意的是 “超卖” 问题。就比如我最多只能 500 张票,但我的买票系统让 501 个人都买到票了,这就是“超卖”问题。这种问题是由于线程竞争资源导致的。传统的解决方式是加锁,这里介绍通过 Redis 事务解决方案。

使用 redis 事务机制的话,就可以把 获取票数、判断 票数大于 0和票数减一 这三个操作打包成一个事务,再加上 Redis 服务器本身是 单线程模型,这样就可以保证不会出现竞争资源导致的超卖问题。

二、事务相关操作

总体认识

事务的核心操作就是 MULTI(开启事务)、EXEC(真正执行事务)、DISCARD(放弃事务)、WATCH(监控 key 的变化)

  • MULTI : 开启一个事务,执行成功返回 OK
  • EXEC: 执行这条命令后,将真正执行 “事务队列” 中存放的命令
  • DISCARD: 放弃当前事务,即服务器收到这条命令就会清空队列。之前的操作都不会执行。
  • WATCH : 监控某个 key 的值的变化,防止数据不一致问题。这条命令后面专门讲。

基本操作流程

  1. 开启事务,执行基本的命令。
  2. 此时,我们可以新开一个客户端查看一下 key1 key2 ,此时key1 key2 仍然为空。
  3. 执行 exec 命令,逐条得到事务中命令的返回值
  4. 之后进行查询就能看到值了

discard 操作:

watch 操作演示

问题场景:

  1. 客户端 1 开启事务,执行 set k1 111。
  2. 在客户端 1 执行 exec 之前,客户端 2 执行 set k1 222
  3. 客户端1 执行 exec

问,此时的 k1 的值?
答案是:111。这是因为set k1 111 实际在 exec 命令之后才会执行,会覆盖客户端2 执行的set k1 222,所以最终的值是 111。

场景示例

  • 客户端 1 开启事务,执行 set k1 111。
  • 在客户端 1 执行 exec 之前,客户端 2 执行 set k1 222
  1. 客户端1 执行 exec,查看 k1 的值

这样就会存在一定的歧义,引入 watch 操作,就能避免上述问题:

WATCH key1 [key2 key3 ...]

原理:

  • 当开启事务的时候, 如果对 watch 的 key 进⾏修改, 就会记录当前 key 的 “版本号”. (版本号是个简单的整数, 每次修改都会使版本变⼤. 服务器来维护每个 key 的版本号情况)
  • 在真正提交事务的时候, 如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号, 就会让事务执⾏失败. (事务中的所有操作都不执⾏).

演示

  1. 删除 k1 防止之前值的干扰,客户端1 先watch k1 再开启事务,执行 set k1 111。
  2. 客户端 2 执行 set k1 222
  3. 客户端1 执行 exec ,再查看 k1 的值

watch 原理

Redis 的 WATCH 命令是实现乐观锁的核心机制,用于在事务执行前监控指定的键,确保事务执行的原子性和一致性。其底层原理可以总结为以下几个关键点:

  1. 版本号机制

    • Redis 为每个键(key)维护一个版本号(本质是一个整数计数器)。
    • 每当键被修改(无论是通过 SETINCR 等命令),其版本号会自动加 1
    • 版本号由 Redis 服务器在底层自动管理,用户无需手动干预
  2. 监控键的版本快照

    • 当执行 WATCH key1 [key2 ...] 时,Redis 会记录当前被监控键的最新版本号,形成一个“版本快照”。
  3. 事务执行的版本校验

    • 执行 WATCH 后,用户通过 MULTI 开启事务,然后编写一系列命令(如 SET、HSET 等)。
    • 当通过 EXEC 提交事务时,Redis 会做一次版本校验
    • 检查所有被 WATCH 的键,当前服务器上的版本号是否与 WATCH 时记录的“版本快照”一致。
      • 如果全部一致:说明事务期间没有其他客户端修改这些键,事务正常执行,所有命令生效。
      • 如果有任何一个键的版本号不一致:说明该键被其他客户端修改过,事务整体取消所有命令都不执行),EXEC 返回 nil 表示事务失败。
  4. 乐观锁的体现

    • WATCH 的设计基于“乐观锁”思想:默认认为事务执行期间不会有并发修改,因此不主动加锁阻塞其他操作。
    • 只有在提交时通过版本号比对发现冲突,才放弃执行,避免了悲观锁的性能开销。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/92663.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/92663.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/92663.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis学习之自定义映射resultMap(七)

这里写目录标题一、准备工作1、新建maven工程2、准备两张表3、建立mapper、pojo、映射文件mapper接口pojoxxxMapper.xml二、resultMap处理字段和属性的映射关系1、用起别名的方式保证字段名与属性名一致2、逐一设置resultMap映射关系3、配置mapUnderscoreToCamelCase三、多对一…

数学学习 | 高数、线代、概率论及数理统计荐书

注:本文为 “数学学习书目推荐” 相关合辑。 略作重排,如有内容异常,请看原文。 高等数学、线性代数及概率论与数理统计领域推荐书目 西湖边的卡夫卡 编辑于 2023-09-19 13:26 7495 人赞同了该回答 数学具有内在的美学属性,但并非…

【LLM实战|langgraph】langgrpah基础

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 langgraph 基础 1. Chatbot实现 # !pip install langchain # !pip install langgraphfrom typing import Annotatedfrom typing_extensions import Typ…

大疆无人机使用eport连接Jetson主板实现目标检测

所需硬件设备如下: 实现原理: 视频流获取:从大疆无人机获取实时视频流。数据传输:将视频流传输至 Jetson 平台。目标检测处理:在 Jetson 上运行目标检测算法对传入的视频帧进行分析 EPort开发套件 大疆官网给出了…

Typora激活与使用

Typora下载 下载地址:Typora 官方中文站 Typora(1.9.5及其以前的版本) 工具:待补充 流程 1.解压工具 2.将license-gen.exe、node_inject.exe两个文件放于typora安装目录下 3.在typora安装目录下运行cmd(可以打开…

图片拆分工具,自定义宫格切割

软件介绍 今天推荐一款实用的图像处理工具——lmage Splitter,支持图像拆分与格式互转功能,无广告干扰,操作简单流畅,满足多样化图片编辑需求。 软件优势 该工具为绿色版设计,无需安装即可直接运行,下载…

23种设计模式解析--创建型模式

创建型模式(造物主的智慧) 单例模式 模式定义 单例模式(Singleton)确保一个类仅有一个实例,并提供该实例的全局访问点。核心思想是通过私有化构造函数和静态成员实现受控的对象创建。核心实现要点 私有构造函数&#x…

全面解析软件工程形式化说明技术

一、形式化说明技术概述:从模糊到精确的跨越 在软件工程的发展历程中,需求说明技术始终是确保软件系统成功开发的关键环节。从早期依赖自然语言的非形式化描述,到如今基于数学和逻辑的形式化方法,这一领域经历了从模糊到精确的深…

百度网盘自动启动如何关闭,关闭智能看图

#某度软件引起的奔溃#在日常办公中,有时候双击图片,会自动打开了某度的网盘,很奇怪莫名其妙的为什么会关闭网盘后又自动打开了。如何发现是某度的牛虻软件在搞鬼的?我右键图片,选择打开方式,发现有“智能看…

疏老师-python训练营-Day40训练和测试的规范写法

浙大疏锦行 知识点回顾: 彩色和灰度图片测试和训练的规范写法:封装在函数中展平操作:除第一个维度batchsize外全部展平dropout操作:训练阶段随机丢弃神经元,测试阶段eval模式关闭dropout 作业:仔细学习下测…

【重磅发布】flutter_chen_keyboard -专注于键盘相关功能

flutter_chen_keyboard 一个功能强大且易于使用的 Flutter 键盘增强库,专为提升移动应用的键盘交互体验而设计。 📖 库简介 flutter_chen_keyboard 是一个专注于键盘相关功能的 Flutter 工具库,旨在为开发者提供更流畅、更智能的键盘交互解决…

idea设置注释--带日期和作者和描述

最终效果 在File Header中添加如下内容: /*** author ${USER}* date ${DATE} ${TIME}* description ${DESCRIPTION}*/${USER}:IDEA 里设置的用户名 ${DATE}:当前日期 ${TIME}:当前时间 可以加自定义变量,比如 ${DESCRI…

【Linux】Socket编程——UDP版

📝前言: 这篇文章我们来讲讲Linux——udpsocket 🎬个人简介:努力学习ing 📋个人专栏:Linux 🎀CSDN主页 愚润求学 🌄其他专栏:C学习笔记,C语言入门基础&#…

RabbitMQ面试精讲 Day 14:Federation插件与数据同步

【RabbitMQ面试精讲 Day 14】Federation插件与数据同步 开篇 欢迎来到"RabbitMQ面试精讲"系列第14天,今天我们将深入探讨RabbitMQ Federation插件与跨集群数据同步机制。在分布式系统架构中,如何实现消息队列集群间的数据同步是确保业务连续…

AI编程工具 | Trae介绍

描述需求就可以自动创建可运行的完整项目了,确实很强! 终端中的报错信息都可以快速作为上下文输入,点击确认就可以自动修改,贼好使! Trae 编程工具详细介绍 一、产品简介 Trae 是字节跳动于 2025 年 1 月 19 日推出的…

【第11话:感知算法基础3】目标检测:深度学习目标检测模型介绍入门及常用模型详解

深度学习目标检测模型介绍入门及常用模型详解 目标检测是计算机视觉的核心任务,需同时完成目标定位(输出边界框坐标)和目标分类(识别类别)。深度学习通过端到端训练显著提升了检测精度和效率,主要分为两类架…

稿定科技:多云架构下的 AI 存储挑战与 JuiceFS 实践

稿定科技(gaoding.com)是一家专注于为企业和个人提供视觉内容创新方案的科技公司,致力于打造全新的设计方式,帮助更多用户轻松掌控设计,创造价值。 随着 AI 技术的加速发展,数据存储和管理成为支撑公司创新…

徘徊识别场景误报率↓77%:陌讯动态时序建模方案实战解析

原创声明本文为原创技术解析,核心技术参数与架构设计参考自《陌讯技术白皮书》,转载请注明来源。一、行业痛点:徘徊识别的现实困境在安防监控领域,徘徊行为识别是保障公共安全的关键技术(如商场防盗窃、园区防闯入等场…

C# 通过第三方库INIFileParser管理INI配置文件

C# 通过第三方库INIFileParser管理INI配置文件目录前言一、添加动态库二、添加接口类代码总结前言 很多时候我们是直接调用系统的C库中的GetPrivateProfileString和WritePrivateProfileString接口来实现管理INI文件的,这个接口最久可以追溯到上个世纪80年代&#x…

政府数字化大屏系统 - Flask实现方案

下面我将设计一个基于Flask的政府数字化大屏系统,包含数据可视化、实时监控和统计分析功能,全套代码下载看底部。 设计思路 使用Flask作为后端框架提供数据接口 前端采用响应式设计,适配大屏展示 使用ECharts实现多种数据可视化 模拟实时…