简介
可以一次执行多个命令,本质是一组命令的集合.
一个事务中的所有命令都会序列化,按顺序的串行化执行而不会被其他命令插入,不许加塞
作用
在一个队列中,一次性,顺序性,排他性的执行一系列命令
开启事务示例
remoteSelf: 1 >multi
"OK"
remoteSelf: 1 >set k1 v1
"QUEUED"
remoteSelf: 1 >set k2 v2
"QUEUED"
remoteSelf: 1 >get k1
"QUEUED"
remoteSelf: 1 >exec
1 ) "OK"
2 ) "OK"
3 ) "v1"
放弃事务
remoteSelf: 1 >mget k1 k2
1 ) "v1"
2 ) "v2"
remoteSelf: 1 >multi
"OK"
remoteSelf: 1 >set k1 11
"QUEUED"
remoteSelf: 1 >set k2 22
"QUEUED"
remoteSelf: 1 >discard
"OK"
remoteSelf: 1 >mget k1 k2
1 ) "v1"
2 ) "v2"
一个失败所有的都失败(如果打完命令就报错,此时全部回滚)
remoteSelf: 1 >keys *
1 ) "k2"
2 ) "k1"
3 ) "website"
4 ) "zset01"
remoteSelf: 1 >multi
"OK"
remoteSelf: 1 >set k3 v3
"QUEUED"
remoteSelf: 1 >set k4 v4
"QUEUED"
remoteSelf: 1 >getset k4
"ERR wrong number of arguments for 'getset' command"
remoteSelf: 1 >exec
"EXECABORT Transaction discarded because of previous errors."
remoteSelf: 1 >keys *
1 ) "k2"
2 ) "k1"
3 ) "website"
4 ) "zset01"
一个失败其他的成功(如果打完命令没有报错,进入队列,运行时报错,则其他的运行成功,报错的失败)
remoteSelf: 1 >keys *
1 ) "k2"
2 ) "k1"
3 ) "website"
4 ) "zset01"
remoteSelf: 1 >mget k1 k2
1 ) "v1"
2 ) "v2"
remoteSelf: 1 >multi
"OK"
remoteSelf: 1 >incr k1
"QUEUED"
remoteSelf: 1 >set k3 v3
"QUEUED"
remoteSelf: 1 >exec
1 ) "ERR value is not an integer or out of range"
2 ) "OK"
remoteSelf: 1 >keys *
1 ) "website"
2 ) "zset01"
3 ) "k1"
4 ) "k2"
5 ) "k3"
watch监控.如果监控的数据发生了改变,则事务失效
悲观锁
pessimistic lock ,每次拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,
这样别人想拿这个数据就会block直到拿到锁.
传统的关系型数据库里边就用到了很多这种锁机制,比如行所,表锁等,读锁,写锁等,都是在操作之前先上锁
乐观锁
optimistic lock ,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,
可以使用版本号等机制.乐观锁适用于多读的应用类型,这样可以提高吞吐量.
乐观锁策略: 提交版本必须大于记录当前版本才能执行更新
示例
127.0.0.1:8686[1]> mget balance debt
1 ) "100"
2 ) "0"
127.0.0.1:8686[1]> watch balance
OK
remoteSelf: 1 >set balance "200"
"OK"
remoteSelf: 1 >get balance
"200"
127.0.0.1:8686[1]> multi
OK
127.0.0.1:8686[1]> decrby balance 20
QUEUED
127.0.0.1:8686[1]> incrby debt 20
QUEUED
127.0.0.1:8686[1]> exec
(nil )
watch
watch指令,类似乐观锁,事务提交时,如果key的值已经被别的客户端改变,整个事务队列都不会被执行.
通过watch命令在事务执行之前监控了多个keys ,倘若在watch之后有任何key的值发生了变化,
exec 命令执行的事务都被放弃,同时返回Nullmulti-bulk应答已通知调用者事务执行失败
exec执行之后会取消对所有key的监控
127.0.0.1:8686[1]> get test
"10"
127.0.0.1:8686[1]> mget balance debt
1 ) "200"
2 ) "0"
127.0.0.1:8686[1]> watch balance test
OK
127.0.0.1:8686[1]> multi
OK
remoteSelf: 1 >set balance "100"
"OK"
remoteSelf: 1 >get balance
"100"
127.0.0.1:8686[1]> incr balance
QUEUED
127.0.0.1:8686[1]> decr debt
QUEUED
127.0.0.1:8686[1]> exec
(nil )
127.0.0.1:8686[1]> mget balance debt
1 ) "100"
2 ) "0"
127.0.0.1:8686[1]> get test
"10"
remoteSelf: 1 >set test "20"
"OK"
remoteSelf: 1 >get test
"20"
127.0.0.1:8686[1]> multi
OK
127.0.0.1:8686[1]> incr test
QUEUED
127.0.0.1:8686[1]> exec
1 ) (integer) 21
unwatch会取消所有key的监控
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端