Redis(八):进阶篇 - 事务
2021/6/27 19:22:21
本文主要是介绍Redis(八):进阶篇 - 事务,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
事务(Transaction)
1、概述
Redis中的事务是一组命令的集合。事务同命令一样都是Redis的最小执行单位,一个事务中的命令要么都执行,要么都不执行。例如,银行转账过程中A给B汇款,首先系统从A的账户中将钱划走,然后向B的账户增加相应的金额。这两个步骤必须属于同一个事务,要么全执行,要么全不执行。否则只执行第一步,钱就凭空消失了,这显然让人无法接受。
事务的原理是先将一个事务的命令发送给Redis,然后再让Redis依次执行这些命令,如:
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> sadd user:1:f 2 QUEUED 127.0.0.1:6379(TX)> sadd user:2:fing 1 QUEUED 127.0.0.1:6379(TX)> exec 1) (integer) 1 2) (integer) 1
以上代码演示了事务的使用方式。
首先使用MULTI命令告诉Redis:“下面我发给你的命令属于同一事务,你先不要执行,而是把它们暂时存起来。”Redis回答:“OK。”
而后我们发送了两个SADD命令来实现添加元素,可以看到Redis遵守了承诺,没有执行这些命令,而是返回QUEUED表示这两条命令已经进入等待执行的事务队列中了,
当把所有要在同一事务中执行的命令都发给Redis后,我们使用EXEC命令告诉Redis将等待执行的事务队列中所有命令(即刚才所有返回QUEUED的命令)按照发送顺序依次执行。EXEC命令的返回值就是这些命令的返回值组成的列表,返回值顺序和命令的顺序相同。
Redis保证一个事务中的所有命令要么都执行,要么都不执行。如果在发送EXEC命令前客户端断线了,则Redis会清空事务队列,事务中的所有命令都不会执行。而一旦客户端发送了EXEC命令,所有的命令就都会被执行,即使此后客户端断线也没关系,因为Redis中已经记录了所有要执行的命令。
除此之外,Redis的事务还能保证一个事务内的命令依次执行而不被其他命令插入。试想客户端A需要执行几条命令,同时客户端B发送了一条命令,如果不使用事务,则客户端B的命令可能会插入到客户端A的几条命令中执行。如果不希望发生这种情况,也可以使用事务。
2、错误处理
如果一个事务中某个命令执行出错,Redis会怎样处理呢?要知道怎样处理,首先需要知道什么原因会导致命令执行出错。
2.1、语法错误
语法错误指命令不存在或命令参数的个数不对。如:
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set key 1111 QUEUED 127.0.0.1:6379(TX)> set key (error) ERR wrong number of arguments for 'set' command 127.0.0.1:6379(TX)> eeeee key (error) ERR unknown command `eeeee`, with args beginning with: `key`, 127.0.0.1:6379(TX)> exec (error) EXECABORT Transaction discarded because of previous errors.
跟在MULTI命令后执行了3个命令:一个正确的命令,成功加入事务队列;其余两个命令都有语法错误。而只要有一个命令有语法错误,执行EXEC命令后Redis就会直接返回错误,连语法正确的命令也不会执行。
版本差异
Reids2.6.5之前的版本会忽略有语法错误的命令,然后执行事务中其他依法正确的命令。
2.2、运行错误
运行错误指在命令执行时出现的错误,比如使用散列类型的命令操作集合类型的键,这种错误在实际执行之前Redis是无法发现的,所以在事务里这样的命令是会被Redis接受并执行的。如果事务里的一条命令出现了运行错误,事务里其他的命令依然会继续执行(包括出错命令之后的命令)。如:
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set key 1 QUEUED 127.0.0.1:6379(TX)> sadd key 2 QUEUED 127.0.0.1:6379(TX)> set key 3 QUEUED 127.0.0.1:6379(TX)> exec 1) OK 2) (error) WRONGTYPE Operation against a key holding the wrong kind of value 3) OK 127.0.0.1:6379> get key "3"
从以上代码可以看出,虽然SADD key 2
出现了错误,但是SET key 3
依然执行了。
Redis的事务没有关系数据库事务提供的回滚功能。为此开发者必须在事务执行出错后,自己收拾剩下的摊子(将数据库复原回事务执行前的状态等)。
3、WATCH命令介绍
WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到EXEC命令(事务中命令是在EXEC之后才执行的,所以在MULTI命令后可以修改WATCH监控的键值),如:
127.0.0.1:6379> set key 1 OK 127.0.0.1:6379> watch key OK 127.0.0.1:6379> set key 2 OK 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set key 3 QUEUED 127.0.0.1:6379(TX)> exec (nil) 127.0.0.1:6379> get key "2"
以上代码在执行WATCH命令后,事务执行前修改了key的值(即SET key 2
),所以最后事务中的命令SET key 3
没有执行,EXEC命令返回空结果。
在不同客户端也是一样,如在A客户端WATCH key
键,在B客户端改变key的值,A客户端的事务也不会执行。如:
A客户端: 127.0.0.1:6379> watch key OK 127.0.0.1:6379> multi OK 在这里执行B客户端的代码: 127.0.0.1:6379> set key 222 OK 127.0.0.1:6379> set key 333 OK 继续执行A客户端 127.0.0.1:6379(TX)> set key 4 QUEUED 127.0.0.1:6379(TX)> exec (nil) 127.0.0.1:6379> get key "333"
author:su1573
鄙人记录生活点滴,学习并分享,请多指教!!!
如需交流,请联系 sph1573@163.com,鄙人看到会及时回复
这篇关于Redis(八):进阶篇 - 事务的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-31Tiny RDM:你的下一代Redis桌面GUI神器-icode9专业技术文章分享
- 2024-03-21redisinsight-v2
- 2024-02-26Typed property App\Api\Mapper\GamePropsConfigMapper::$apiRedis must not be accessed before initia-icode9专业技术文章分享
- 2024-02-21redisson getlock
- 2024-02-20redis config
- 2024-02-20redis leaderboard
- 2024-01-23缓存选型:Redis or MemCache
- 2024-01-22面试官:Redis持久化能关吗?怎么关?
- 2024-01-21Redis压测工具redis-benchmark-icode9专业技术文章分享
- 2024-01-19这才是你应该了解的Redis数据结构!