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

尚硅谷redis7 47-48 redis事务之理论简介

47 redis事务之理论简介

什么是事务

可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入

能干什么?

一个队列中,一次性、顺序性、排他性的执行一系列操作

redis事务vs数据库事务

1 单独的隔离操作

        Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的

2 没有隔离级别的概念

        因为事务提交前任何指令都不会被实际执行【只是放在队列里面不会执行】,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了

3不保证原子性

        Redis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力

4 排它性

        Redis会保证一个事务内的命令依次执行,而不会被其它命令插入

48 redis事务之案例实操

Redis 事务是通过 MULTI 命令进入的。该命令始终返回 OK。此时,用户可以发送多个命令,但 Redis 不会立即执行这些命令,而是将它们排入队列中。所有命令会在调用 EXEC 命令后一次性执行。

如果调用 DISCARD 命令,则会清空事务队列并退出事务

redis事务命令

1.DISCARD        取消事务→放弃执行事务块内的所有命令。

2.EXEC        执行所有事务块内的参令。

3.MULTI        标记一个事务块的开始。

4.UNWATCH        取消WATCH 命令对所有key的监视,

5.WATCH key [key .. ]        监视一个(或多个)key,如果在事劳执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。

CASE1:正常执行

MULTI 和 EXEC

CASE2:放弃事务

MULTI 和 DISCARD

CASE3:全体连坐

一条命令出错,就全部放弃执行

127.0. 0.1:6379> MULTI
OK
127. 0. 0. 1: 6379(TX)> set k1 v111
QUEUED
127.0. 0. 1: 6379( TX)> set k2 v222
QUEUED
127.0.0.1:6379(TX)> set k3   // 这个命令本身就是错误的
(error) ERR wrong number of arguments for 'set' command
127. 0. 0. 1: 6379( TX) >
127. 0. 0. 1: 6379( TX) > EXEC
EXECABORT Transaction discarded because of previous errors.  //事务队列中的所有命令都不执行

事务中的错误

在事务过程中,可能会遇到两类命令错误:

  1. 命令在排队阶段失败:也就是说,在调用 EXEC 之前就发生了错误。例如,命令可能存在语法错误(参数数量错误、命令名称错误等),或者遇到某些关键问题,如内存不足(例如服务器配置了 maxmemory 指令设置了内存上限)。

    1. 这种情况只能全部命令都放弃执行

  2. 命令在 EXEC 后执行时失败:例如,对某个键执行了不适用的操作(比如对一个字符串类型的键执行列表操作)。

CASE4:冤头债主

在执行 EXEC 之后发生的错误不会被特殊处理:即使事务中的某个命令执行失败,其他命令仍然会被继续执行。

总结:对的放行,错的不执行

补充:redis不提供事务回滚的功能,开发者必须在事务执行出错后,自行恢复数据库状态。

INCR email命令错误:邮箱是字符串不可能自增

CASE5:watch监控

redis的watch类似于乐观锁的设定,类似于CAS

悲观锁是一种假设“总会发生冲突”的锁机制。假设每次访问数据都是对数据进行修改。因此在对数据进行操作前,会先加锁,防止其他线程同时访问,以确保数据安全。

乐观锁假设“并发冲突是少数”,所以不加锁。 假设每次访问数据都不会修改数据。因此在更新数据时才校验数据是否被其他线程修改。

CAS 是一种无锁的原子操作,全称是 比较并交换。它是乐观锁的具体实现方式之一,底层依赖于 CPU 的原子指令。

工作原理:

  • 先读取变量的旧值

  • 和预期值进行比较

  • 如果相等,则更新为新值

  • 如果不等,说明有其他线程修改过,则重试或失败

watch

初始化k1和balance两个key,先监控再开启multi,保证两key变动在同一个事务内

127. 0. 0. 1:6379> set k1 abc
OK
127. 0. 0. 1: 6379> set balance 100
OK
127. 0. 0. 1:6379>
127. 0. 0. 1: 6379> WATCH balance
OK
127.0. 0.1:6379>
127. 0. 0. 1: 6379> MULTI
OK
127. 0. 0. 1: 6379( TX) > set k1 abc2
QUEUED
127. 0. 0. 1: 6379( TX) > set balance 110
QUEUED
127. 0. 0. 1: 6379( TX) > EXEC
1) OK
2) OK
127.0. 0. 1:6379> get k1
"abc2"

有加塞篡改:

        客户端1监控了balance

        客户端2修改了balance

        客户端1的事务执行失败返回空

unwatch

UNWATCH 用于 取消之前通过 WATCH 命令监视的所有键,避免这些键的变动影响事务的执行。

  • 在你使用 WATCH 命令监控某些键的变化时,如果你不再想基于这些键判断是否执行事务,就可以用 UNWATCH 来取消。

  • 如果你调用了 DISCARD,Redis 会自动 UNWATCH,无需手动取消。

WATCH mykey
GET mykey
UNWATCH       # 取消监视
MULTI
SET mykey "newvalue"
EXEC

小结

一旦执行了exec之前加的监控锁都会被去掉。

当客户端连接丢失【比如退出连接】,所有东西都会被取消监视

相关文章:

  • 【Vue3】生命周期 hook函数 toRef
  • Foupk3systemX5OSNTXPro引擎
  • 什么是MCP技术,跟http技术有什么区别
  • SpringBoot集成Tika实现文档解析
  • 互联网医疗问诊APP原型设计:12个实战案例解析
  • 计算机组成与体系结构:硬盘驱动器(Hard Disk Drives)
  • 有趣的游戏化单词学习 APP
  • 【FAQ】spring boot 3 集成 nacos
  • MyBatis-Plus一站式增强组件MyBatis-Plus-kit(更新2.0版本):零Controller也能生成API?
  • 数据库MySQL学习——day13(索引与查询优化)
  • 深度解读 Qwen3 大语言模型的关键技术
  • 2025年上半年软考系统架构设计师--案例分析试题与答案
  • 使用Auto-Coder对js文件进行审计并修复漏洞1.3 1.4 1.5版本
  • 组合API-provide和inject函数
  • 颠覆传统,智领未来——UMI企业智脑:重新定义企业智能化转型的全新可能
  • SIGGRAPH 2025 | 快手可灵团队提出3D感知的电影级文本到视频生成框架CineMaster
  • 视频监控联网系统GB28181协议中历史视音频的回放流程详解以及查询失败常见原因
  • 测试 Gemini Pro 2.5
  • 电机控制杂谈(26)——电机驱动系统的编码器的测速噪声
  • 迪米特法则 (Law of Demeter, LoD)
  • 顺的网络做网站好不好/百度百度推广
  • 网页游戏名字排行榜/seo关键词优化排名
  • 加强社区网站建设/西安优化外
  • 界面设计最好的网站/湖南网站建设效果
  • WordPress主题Cute主题/广州seo诊断
  • 领优惠券的网站怎么建设的/免费外国网站浏览器