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

Redis(四)——事务

说到事务我想大家都不陌生,因为我们日常中对事务的使用还是蛮场景的,最常见的就是mysql的事务,也就是我们关系型数据库的事务,那么redis这个非关系型数据库在事务方面和myql这个关系型数据库有什么区别呢?

redis事务和mysql事务对比

特性

Redis事务

MySQL事务

本质差异

ACID特性

部分支持(无隔离性)

完全ACID支持

根本区别

隔离级别

无隔离性

4种隔离级别

核心差异

执行方式

批量执行

实时执行

行为差异

回滚机制

无回滚(仅取消)

完整回滚

关键区别

锁机制

WATCH命令(乐观锁)

悲观锁(行锁、表锁)

并发控制

使用场景

批量操作、简单原子性

复杂业务、数据一致性

定位不同

从上面的表可以看出redsi的事务其实是mysql的阉割版本,没有隔离性,还记得mysql的隔离性是由什么构成的吗?没错就是锁机制和MVCC来保障隔离性的。

但是Redis和mysql最大的区别就是,redis是一个单线程架构,也就是所有的命令都是排队进行的,所以就不用像mysql一样,因为根本就不存在什么脏读、幻读的问题,但是还是有锁的概念的,因为redis只是命令是单线程的,并不是业务是单线程的。如下:

# 问题场景:余额检查+扣款(非原子操作)
# 客户端A
127.0.0.1:6379> GET balance:user1
"100"# 此时客户端B也读取余额
127.0.0.1:6379> GET balance:user1  
"100"# 客户端A扣款
127.0.0.1:6379> DECRBY balance:user1 60
(integer) 40# 客户端B也扣款(但余额已不足!)
127.0.0.1:6379> DECRBY balance:user1 60
(integer) -20  # 余额变为负数!数据不一致!# 这就是著名的"超卖"问题

所以redis也是需要锁的,而这个锁的粒度就没有mysq分那么多了,只有一个键锁,顾名思义就是把键锁住,而且是乐观锁,只要不修改,查询什么的都不受到影响。如下:

# Redis的乐观锁机制
# 客户端A
127.0.0.1:6379> WATCH balance:user1  # 开始监控
OK
127.0.0.1:6379> GET balance:user1
"100"
127.0.0.1:6379> MULTI #开启事务
OK
127.0.0.1:6379> DECRBY balance:user1 50
QUEUED# 此时客户端B修改了监控的key
127.0.0.1:6379> DECRBY balance:user1 10  # 客户端B的操作
(integer) 90# 客户端A执行事务
127.0.0.1:6379> EXEC #执行事务
(nil)  # 事务执行失败!因为WATCH的key被修改# 这就是Redis的乐观锁:检测到冲突则放弃执行

事务的特性

redis事务的特点就是批处理,我们使用multi命令开启事务后,其他会话的命令就可以执行了,因为redis是命令单线程的,所有的命令都是排队执行的。而multi命令只是在当前会话开启了一个队列,然后把需要一批执行的命令放入其中,在使用exec命令去执行这批命令,而这个时候事务中命令没执行完其他会话是被阻塞的。所以被叫做批处理。另外其他会话是不能执行这个事务的,每个事务在每个会话都是单独的。

另外就是redis 的事务是没有回滚的,也就是说只要加入事务的时候没错,加入事务的时候没有语法问题,就能够执行,执行成功和执行失败事务不管,他只保障这一批命令是一起执行的。如果放入事务的时候命令被检查出错了,那么整个事务就不能执行了,会被redis自动取消。

命令

语法

作用

返回值

使用场景

注意事项

MULTI

MULTI

标记事务开始,开启一个事务块

始终返回 OK

开始一组原子性操作

只是设置标志,不阻塞其他客户端

EXEC

EXEC

执行事务中的所有命令

返回数组,包含每个命令的执行结果

提交事务,执行队列中的命令

执行期间会阻塞其他客户端命令

DISCARD

DISCARD

取消事务,清空事务队列

始终返回 OK

放弃当前事务中的所有命令

不会执行任何已入队的命令

WATCH

WATCH key [key ...]

监视一个或多个key,乐观锁机制

始终返回 OK

在事务执行前检测key是否被修改

如果WATCH的key被修改,EXEC会失败

UNWATCH

UNWATCH

取消所有WATCH命令对key的监视

始终返回 OK

取消之前的监视,释放资源

通常在事务执行后自动调用

所以要保障业务的一致性,不出现“超卖”的情况单靠事务是不行的,因为事务只是批处理,还是需要使用watch进行监控的。而且watch命令只是一个redis内部的一个监控列表,记录了那个会话监控了那个键,不影响其他会话对这个被监控键的修改和事务,如果被修改了那么这个watch监控的键就会被标记为脏数据,而且也只对开启这个watch的会话有效。

而且watch只作用在当前会话的当前事务,也就是说当前会话如果不开启事务,修改被监控的值也不会出现问题,就更别说其他会话的修改和事务的执行、取消了。

总结就是watch是multi的搭档,他们是一起工作的好朋友。

另外,一旦执行了exec后,之前watch监控就回被清除,还有就是断开链接后,也会关闭清除当前监控或者未执行的事务哦。所以才说事务和监控是当前会话的。

总结

本篇主要说的就是redis事务和watch之间的关系,以及redis事务和mysql事务的区别。

http://www.dtcms.com/a/577580.html

相关文章:

  • 便宜的vps租用网站有哪些网站使用ftp
  • TestKeyDownBit函数和SetKeyDownBit函数和ClearKeyDownBit函数分析
  • RHCSA---权限管理
  • Flutter for HarmonyOS开发指南(二):混合开发架构与通信机制
  • 分布式分片执行原理解析
  • 自主建站全攻略:建站系统的选择指南与深度说明
  • 什么网站有做qq群排名的关键词优化价格
  • 网站内容怎么进行编写
  • SSM 房屋租赁系统
  • 网站排名优化服务公司福建省住房和城乡建设网站
  • 开发集成热门小游戏(vue+js)
  • Java-简单项目开发流程
  • 莱芜网站优化平台现在中型公司做网站用的是什么框架
  • 区块链-B站API程序系统方案
  • LVS三种模式及调度算法解析
  • MySql 9.5.0(2025)-Windows安装步骤
  • 查看 MySQL 数据库里的所有信息,包括表结构、数据内容
  • Rocky10 使用kubeadm 安装k8s 单节点
  • K8s 中的Serviceaccount
  • MySQL 事务的两种使用方式
  • 【MySQL 进阶】高性能优化
  • 如何做静态页网站wordpress swf 上传
  • Dotnet-Dapper的用法
  • 深入理解 Spring Boot 中的数据库迁移:Flyway 与 Liquibase 实战指南
  • 使用visa进行仪器控制
  • 百度网站验证创意交易平台官网
  • Node.js异步编程的多种实现方式:从回调地狱到优雅的async/await
  • 全面评测 | Photoshop 2026 新特性深度解析与实测体验
  • FastAPI深度解析
  • wordpress会员数据共同盐城网络优化