Redis 事务

前言

Redis事务主要由MULTI 、 EXEC、DISCARD、WATCH和UNWATCH这些基础命令构成。

"Redis作为一种高性能的内存数据库,提供了强大的事务支持,使得用户可以将多个命令打包成一个事务单元进行执行。Redis事务具有原子性、隔离性、一致性和持久性的特点,能够确保一组命令要么全部执行成功,要么全部执行失败。在Redis中,通过MULTI命令开启事务,然后将多个命令添加到事务队列中,最后通过EXEC命令执行整个事务。此外,还可以使用DISCARD命令取消事务或使用WATCH命令实现乐观锁。接下来让我们详细了解Redis事务操作的使用方法和注意事项。"

一、事务操作

1)MULTI

语法:MULTI

用于标记事务的开始,后续客户端执行的命令都将被存入一个命令队列,直到执行EXEC时,这些命令才会被执行。

2)EXEC

语法:EXEC

执行命令队列中的所有命令,但如果在启用一个事务之前执行了WATCH命令,那么只有当WATCH所监控的keys没有被修改的前提下,EXEC命令才能执行事务队列中的所有命令,并返回所有命令的执行结果,否则EXEC将放弃当前事务中的所有命令。

3)DISCARD

语法:DISCARD

取消事务队列中的所有命令,并将当前连接的状态恢复为非事务状态。如果WATCH命令被使用,会自动执行UNWATCH取消监视的所有keys。

4)WATCH

语法:WATCH keykey...

WATCH命令类似于关系型数据库的乐观锁,可以在启用事务之前监视某些keys的变化。在MULTI命令执行之前,可以指定需要监视的keys,在执行EXEC之前,如果被监控的keys发生修改,EXEC将放弃执行该队列中的所有指令。并且WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。

首先打开一个客户端,并使用watch命令监视user:1001的key,接着使用multi启用事务。

然后打开第二个客户端,并修改key为user:1001的value为user01。

最后回到第一个客户端再次对key为user:1001的value修改为user001,并执行exec命令。由于user:1001这个key被第一个客户端所监视,而这个key在启用事务前被第二个客户端修改了,因此当第一个客户端启用事务后再对其进行修改时这是无效的,Redis将放弃队列中的所有指令,返回了(nil)。

5)UNWATCH

语法:WATCH keykey...

取消当前事务中指定监控的keys。如果执行了EXEC或DISCARD命令,则无需再手工执行该命令了,因为在此之后UNWATCH命令会自动执行,事务中所有的keys都将自动取消监控。

二、原子性

在关系型数据库中的原子性代表一系列不可分割的操作,要么全部执行成功,要么全部不执行。如果执行过程中产生了错误或者异常,那么事务将会自动回滚。而在Redis的事务中是否具备原子性呢?我们看看以下两种情况,并得出相关的结论。

1、错误指令

在使用multi命令开启事务之后,然后输入一些命令,其中包含一个错误的命令。

从结果来看似乎有点符合我们对事务的理解。但仔细想想,这只是在输入命令的时候产生语法的错误,Redis对其进行了校验,报错之后Redis就放弃了这个事务。因此得出的结论是:Redis在启用事务输入操作命令时是原子操作,它会对命任何一个命令进行语法检查,当输入有误时,Redis会清空队列并放弃事务。

2、运行时错误

如果输入的命令都正确,而在执行这些命令时产生了错误,Redis是否会取消所有命令并放弃事务呢?看下面的例子。

当执行到第二条命令时产生了错误(用户名不是一个整型数值,并不能自增),但是前面和后面的命令都执行成功。并不会因为执行了一个错误的命令而回退所有已经执行成功的命令并放弃整个事务。因此得出的结论是:Redis在执行命令队列时并不是原子性的,通俗点说就是Redis本身并不支持事务的回滚机制。

三、总结

在 Redis 中,事务(Transaction)是一种将多个命令打包执行的机制,以确保这些命令要么全部执行,要么全部不执行的特性。通过使用事务,可以将一系列命令打包成一个整体,然后一次性地执行它们,同时保证这些命令的原子性。

在 Redis 中,使用事务需要遵循以下步骤:

  1. MULTI 命令:使用 MULTI 命令标记事务的开始。之后的命令都会被放入一个队列中等待执行。在 MULTI 命令之后,每个命令都会被放入事务队列,而不是立即执行。

  2. 添加命令到事务队列:在 MULTI 命令之后,你可以依次添加需要执行的命令到事务队列中。这些命令并不会立即执行,而是被暂时保存起来。

  3. 执行事务:使用 EXEC 命令来执行整个事务中的所有命令。当执行 EXEC 命令时,Redis 将按照命令在事务队列中的顺序依次执行这些命令,并返回执行结果。如果事务中的任何一条命令执行失败,那么整个事务都会被取消。

  4. 原子性保证:在执行事务期间,其他客户端无法对事务中涉及的键进行修改。这意味着事务中的所有命令要么全部执行,要么全部不执行,没有部分执行的情况。

通过使用 Redis 事务,你可以批量执行多个命令,并且在执行过程中保持原子性,这对于需要一次性执行多个操作,或者需要确保数据一致性的场景非常有用。

相关推荐
是上好佳佳佳呀5 分钟前
MySQL 基础:从数据库概念到表结构管理DDL
数据库·mysql
Nturmoils7 分钟前
Oracle 迁移评估时,我把这两类问题列在了检查清单最前面
数据库
Database_Cool_18 分钟前
数据库性能不够用,升级到什么方案好?阿里云 PolarDB(云原生数据库领导者,兼容 MySQL/PostgreSQL/Oracle)平滑升级与百倍弹性
数据库·阿里云·云原生
程序猿秃头之路22 分钟前
DDD 系列:聚合和聚合根详解
数据库·oracle·ddd·领域驱动设计
码上上班1 小时前
Mongodb课程
数据库·mongodb
农村小镇哥1 小时前
Oracle中的锁和10704对高级队列锁
数据库·oracle
峥无2 小时前
SQL性能调优:从执行计划看懂索引的使用与失效
数据库·sql
xyj29175964112 小时前
在Trae中配置数据库MCP
数据库·ai·mcp
廋到被风吹走2 小时前
【AI】【Claude】从 Prompt 到 Agent 的完整进阶地图
数据库·人工智能·prompt
数智化管理手记2 小时前
智能财务能替代人工核算吗?智能财务核心功能包含哪些?
大数据·网络·数据库·数据挖掘·精益工程