当前位置:网站首页>Redis的事务
Redis的事务
2022-06-27 08:06:00 【小月亮6】
Redis的事务
是什么:
官网:https://redis.io/topics/transactions
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行执行而不会被其它命令插入
可以看成,一个队列中,一次性、顺序性、排他性的执行一系列命令
需要注意的是,即使一个命令失败,队列中的所有其他命令都会被处理,Redis不会停止对命令的处理。说白了就是不具有原子性;
怎么玩:
序号 | 命令及描述 |
---|---|
1 | DISCARD 取消事务,放弃执行事务块内的所有命令。 |
2 | EXEC 执行所有事务块内的命令。一旦执行了exec之前加的监控锁都会被取消掉了(watch监控的key) |
3 | MULTI 标记一个事务块的开始。 |
4 | UNWATCH 取消 WATCH 命令对所有 key 的监视。 |
5 | WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
实例1:正常执行
multi开启一个事务,exec执行所有事务内的命令,在exec之前所有的操作均未提交,开启新的线程窗口时访问不到
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) "v1"
127.0.0.1:6379> get k2
"v2"
实例2:放弃执行
multi开启一个事务,discard放弃所有事务内的命令,所有事务内的命令都是无效的
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k2 xiaoming
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379>
实例3:全体连坐
multi开启一个事务,只要在编译期间(语法上)有一个报错的,那么这个事务内所有的命令都会提交失败
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 vvvvv
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> set k5 v5
QUEUED
127.0.0.1:6379> setsetset k6 v6
(error) ERR unknown command 'setsetset'
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379>
实例4:冤家债主
multi开启一个事务,只要在编译期间(语法上)没有报错,那么这个事务内的命令,运行时错误命令会失败,其他的命令还是会成功
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k22 v22
QUEUED
127.0.0.1:6379> get k4
QUEUED
127.0.0.1:6379> incr k1
QUEUED
127.0.0.1:6379> set k33 v33
QUEUED
127.0.0.1:6379> exec
1) OK
2) (nil)
3) (error) ERR value is not an integer or out of range
4) OK
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k22"
4) "k33"
5) "k1"
127.0.0.1:6379> get k22
"v22"
127.0.0.1:6379>
所以,从严格意思上来说,redis并不支持事务,或者说部分支持事务
watch监控:
实例1:正常执行
127.0.0.1:6379> get k22
"v22"
127.0.0.1:6379> set balance 100
OK
127.0.0.1:6379> set debt 0
OK
127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> decrby balance 20
QUEUED
127.0.0.1:6379> incrby debt 20
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 80
2) (integer) 20
127.0.0.1:6379>
实例2:异常修改
就是在进程一对watch balance时,进程二(或者说线程)对balance进行了修改,这样事务就会失败
线程一
127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> decrby balance 20
QUEUED
127.0.0.1:6379> incrby debt 20
QUEUED
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> clear
127.0.0.1:6379> get balance
"800"
127.0.0.1:6379>
线程二
127.0.0.1:6379> get balance
"80"
127.0.0.1:6379> set balance 800
OK
127.0.0.1:6379>
unwatch取消
正如上面所说的 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断
127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> set balance 500
OK
127.0.0.1:6379> unwatch
OK
127.0.0.1:6379> get balance
"500"
127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set balance 80
QUEUED
127.0.0.1:6379> set debt 20
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
127.0.0.1:6379> get balance
"80"
127.0.0.1:6379>
Watch总结:
- Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行
- 通过WATCH命令在事务执行之前监控了多个Keys, 倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti- bulk应答以通知调用者事务执行失败
总结:
总体来说事务分为三个阶段:
开启:以MULTI开始一个事务
入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
执行:由EXEC命令触发事务
三个特性:
1、单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
2、没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到"这个让人万分头痛的问题.
3、不保证原子性: redis同一个事 务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚
边栏推荐
- Windows下mysql-8下载、安装、配置教程
- js用while循环计算假如投资多年的利率为5%,试求从1000块增长到5000块,需要花费多少年
- 游戏六边形地图的实现
- Zabbix部署说明(Server+Win客户端+交换机(H3C))
- How to bind SQL statements to web buttons
- Speech signal feature extraction process: input speech signal - framing, pre emphasis, windowing, fft- > STFT spectrum (including amplitude and phase) - square the complex number - > amplitude spectru
- js中判断成绩是否合格,范围在0-100,否则重新输入
- MySQL about auto increment sum cannot be empty
- L'introduction en bourse de Wild Wind Pharmaceutical a pris fin: Yu pinzeng, qui avait l'intention de lever 540 millions de RMB, a effectué un investissement P2P.
- No matter how good LCD and OLED display technologies are, they cannot replace this ancient display nixie tube
猜你喜欢
JS use the switch statement to output the corresponding English day of the week according to 1-7
L'enquête en aveugle a montré que les femmes étaient meilleures que les hommes.
JS to print prime numbers between 1-100 and calculate the total number of optimized versions
[11. two dimensional difference]
The IPO of Yefeng pharmaceutical was terminated: Yu Feng, the actual controller who had planned to raise 540million yuan, made P2P investment
Implementation of game hexagon map
淘宝虚拟产品开店教程之作图篇
js打印99乘法表
Cookie encryption 7 fidder analysis phase
盲测调查显示女码农比男码农更优秀
随机推荐
Is futures reverse documentary reliable?
若xn>0,且x(n+1)/xn>1-1/n(n=1,2,...),证明级数∑xn发散
【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法
Lvgl description 3 about the use of lvgl Guide
【批处理DOS-CMD命令-汇总和小结】-将文件夹映射成虚拟磁盘——subst
關聯GIS:條條道路通UE5城
js用while循环计算假如投资多年的利率为5%,试求从1000块增长到5000块,需要花费多少年
Binary tree structure and heap structure foundation
【批处理DOS-CMD命令-汇总和小结】-环境变量、路径变量、搜索文件位置相关指令——set、path、where,cmd命令的路径参数中有空格怎么办
JS, and output from small to large
Futures reverse Documentary - training for traders
js判断用户输入的数是否为质数(多种方法)
L'enquête en aveugle a montré que les femmes étaient meilleures que les hommes.
ACM课程学期总结
JS to determine whether the result is qualified, the range is 0-100, otherwise re-enter
js成绩奖惩例题
Basic knowledge | JS Foundation
JS print 99 multiplication table
SPARQL基础入门练习
ZABBIX deployment instructions (server+win client + switch (H3C))