Redis事务机制

在进入正文前,我们首先来明确两个概念。

并发编程中的原子性指的是,一组操作"不可拆分、不可中断";数据库事务中的原子性指的是,一组操作"要么执行成功、要么执行失败"。

因此,原子性在并发编程中,和在数据库中是两种不同的概念。

而 Redis 既是一个数据库,又是一个支持并发编程的系统,当我们讨论其原子性时,一定要明确指的是哪个原子性。

一、Redis 中的事务

Redis 支持事务,可以通过 MULTI、EXEC、DISCARD、WATCH、UNWATCH 等命令来实现事务功能。

  • MULTI:标记一个事务块的开始。

使用 MULTI 命令后,可以输入多个命令,Redis 不会立即执行这些命令,而是将它们放到队列,当调用 EXEC 命令后才会执行队列中的所有命令。

  • DISCARD:取消事务,放弃执行事务块内的所有命令。

使用 DISCARD 命令将会清空事务队列中保存的所有命令,从而取消事务的执行。

  • WATCH key [key ...]:监视一个(或多个) key 。

使用 WATCH 命令用于监听指定的键,当调用 EXEC 命令执行事务时,如果一个被 WATCH 命令监视的键被其他命令所修改的话,整个事务都不会执行。

  • UNWATCH:取消 WATCH 命令对所有 key 的监视。

使用 UNWATCH 命令取消所有 key 的监视后,当调用 EXEC 命令执行事务时,如果一个 key 被其他命令所修改的话,不会打断整个事务的执行。

  • EXEC:执行所有事务块内的命令。

如果事务在执行过程中发生错误,Redis 会继续执行剩余的命令而不是回滚整个事务。

所以,Redis 并不满足数据库事务中的原子性,但是满足并发编程中的原子性,即一组操作在执行过程中不可被拆分、不可被中断。

二、为什么Lua脚本可以保证原子性?

因为 Redis 会将 Lua 脚本中的一组操作封装成一个单独的事务,而这个单独的事务会在 Redis 客户端运行时,由 Redis 服务器自行处理并完成整个事务。如果在这个进程中有其他客户端请求的时候,Redis 将会把它暂存起来,等到 Lua 脚本处理完毕后,才会再把被暂存的请求恢复。

这样就可以保证整个脚本是作为一个整体执行的,中间不会被其他命令插入。但是,如果命令执行过程中命令产生错误,事务是不会回滚的,将会影响后续命令的执行。

也就是说,Redis 保证以原子方式执行 Lua 脚本,但是不保证脚本中所有操作要么都执行或者都回滚。

相关推荐
YMatrix 官方技术社区16 分钟前
YMatrix 存储引擎解密:MARS3 存储引擎如何超越传统行存、列存实现“时序+分析“场景性能大幅提升?
开发语言·数据库·时序数据库·数据库架构·智慧工厂·存储引擎·ymatrix
辞砚技术录1 小时前
MySQL面试题——索引2nd
数据库·mysql·面试
linweidong1 小时前
C++thread pool(线程池)设计应关注哪些扩展性问题?
java·数据库·c++
欧亚学术2 小时前
突发!刚刚新增17本期刊被剔除!
数据库·论文·sci·期刊·博士·scopus·发表
黑白极客3 小时前
怎么给字符串字段加索引?日志系统 一条更新语句是怎么执行的
java·数据库·sql·mysql·引擎
码农水水3 小时前
中国邮政Java面试:热点Key的探测和本地缓存方案
java·开发语言·windows·缓存·面试·职场和发展·kafka
大厂技术总监下海3 小时前
数据湖加速、实时数仓、统一查询层:Apache Doris 如何成为现代数据架构的“高性能中枢”?
大数据·数据库·算法·apache
LeenixP3 小时前
RK3576-Debian12删除userdata分区
linux·运维·服务器·数据库·debian·开发板
知行合一。。。3 小时前
Python--03--函数入门
android·数据库·python
X***07884 小时前
理解 MySQL 的索引设计逻辑:从数据结构到实际查询性能的系统分析
数据库·mysql·sqlite