Redis事务

是什么

可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞

能干嘛

一个队列中,一次性、顺序性、排他性的执行一系列命令

案例

常用命令

序号 命令及描述
DISCARD 取消事务,放弃执行事务块内的所有命令
EXEC 执行所有事务块内的命令
MULIT 标记一个事务块的开始
UNWATCH 取消WATCH命令对所有key的监视
WATCH key [key...] 监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断

case1:正常执行

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> INCR count
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK
2) OK
3) OK
4) (integer) 1
127.0.0.1:6379> get count
"1"
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k2
"v2"

case2:放弃事务

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 v11
QUEUED
127.0.0.1:6379(TX)> set k2 v22
QUEUED
127.0.0.1:6379(TX)> INCR count
QUEUED
127.0.0.1:6379(TX)> DISCARD
OK
127.0.0.1:6379> get count
"1"
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k2
"v2"

case3:全体连坐

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 v111
QUEUED
127.0.0.1:6379(TX)> set k2 v222
QUEUED
127.0.0.1:6379(TX)> set k3
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k2
"v2"

case4:冤头债主

127.0.0.1:6379> set email 123456@qq.com
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 v11111
QUEUED
127.0.0.1:6379(TX)> set k2 v22222
QUEUED
127.0.0.1:6379(TX)> INCR count
QUEUED
127.0.0.1:6379(TX)> INCR email
QUEUED
127.0.0.1:6379(TX)> set k3 v3333
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK
2) OK
3) (integer) 2
4) (error) ERR value is not an integer or out of range
5) OK
127.0.0.1:6379> get k1
"v11111"
127.0.0.1:6379> get email
"123456@qq.com"
127.0.0.1:6379> get k3
"v3333"

case5:watch监控

redis使用watch来提供乐观锁定,类似于CAS(check-and-set)

  1. 悲观锁
    顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。
  2. 乐观锁
    顾名思义,就是很乐观,每次去拿数据的时候都会认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据
    乐观锁策略:提交版本必须 大于 记录当前版本才能执行更新
  3. CAS

watch

  1. 初始化K1和balance两个Key,先监控再开启multi,保证两key变动在同一个事务内
127.0.0.1:6379> set k1 abc
OK
127.0.0.1:6379> set balance 100
OK
127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 abc2
QUEUED
127.0.0.1:6379(TX)> set balance 110
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
127.0.0.1:6379> get k1
"abc2"
127.0.0.1:6379> get balance
"110"

  1. 有加塞篡改
    watch命令是一种乐观锁的实现,Redis在修改的时候会检测数据是否被更改,如果更改了,则执行失败

第一个窗口蓝色框第5步执行结果返回为空,也就是相当于是失败
img

unwatch

img

小结

一旦执行了exec之前加的监控锁都会被取消掉了
当客户端连接丢失的时候(比如退出链接),所有东西都会被取消监视

总结

  1. 开启:以multi开始一个事务
  2. 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
  3. 执行:由exec命令触发事务
posted @ 2025-03-05 16:50  小肚腩吖  阅读(13)  评论(0)    收藏  举报