【Redis07】事务

2022-10-26 14:38:38 浏览数 (2)

Redis事务

redis事务就是一个命令执行的队列,将一系列预定义的命令包装成一个整体,在执行时,就按这个顺序依次执行,中间不会被打断或干扰

事务的基本操作

  • 开启事务
代码语言:javascript复制
multi

作用: 设定事务的开启位置,从这句命令之后,后续所有的指令都会被加入事务队列,并不会立刻执行。

  • 执行事务
代码语言:javascript复制
exec

作用: 设定事务的结束位置,同时执行事务,返回事务队列里每条指令的执行结果。

  • 撤销事务
代码语言:javascript复制
discard

作用:终止当前事务的定义,前面添加的语句全部作废

特殊情况

  1. 定义事务的过程中,命令格式输入错误怎么办?
    • 如果是语法错误,那整体事务中的所有命令都不会执行,包括正确的指令
  2. 定义事务的过程中,命令执行错误怎么办?
    • 如果指令格式正确,但执行出现错误,如list的命令被错误的用在了一个string的key上,这时只会执行那些正确的,能执行的命令,错误命令不会执行
    • 已经执行完的数据会被真实反映在内存上,不会自动回滚,需要程序员在代码中捕捉异常后手动回滚。

WATCH

watch 用来对一个或多个key添加监视,一旦被监视的key被修改或删除,那么未执行(exec)的事务就会作废,使用此命令,可以实现乐观锁。

代码语言:javascript复制
watch key1[ key2 ...]

例:

代码语言:javascript复制
127.0.0.1:8100> set junebao:name zhangsan
OK
# 监视 junebao:name
127.0.0.1:8100> watch junebao:name
OK

# 开启事务
127.0.0.1:8100> multi
OK
127.0.0.1:8100> set junebao:age 21

然后换一个shell,修改被监视的junebao:name

代码语言:javascript复制
127.0.0.1:8100> set junebao:name lisi
OK

回到第一个窗口,使用exec来执行事务

代码语言:javascript复制
# 由于被监视的对象改变,事务未执行成功
127.0.0.1:8100> exec
(nil)
127.0.0.1:8100> get junebao:age
"22"
  • 使用UNWATCH取消对所有key的监视(不能单个取消)

使用场景

这条命令可以当作一个简单的乐观锁,比如可以使用watch简单实现Redis中提供的INCR,该操作用来让指定key对应的值自增特定数量,不过重要的是它是一个原子操作。

代码语言:javascript复制
WATCH myvalue
var = GET myvalue
var = var   1

multi
SET myvalue var
exec

这样因为监视了myvalue,所以如果在执行事务的过程中有别的客户端修改了myvalue的值,这里的事务就会被取消,来保证数据一致性。

总结

  1. 不要混淆Redis单进程和事务,单进程只能保证一条指令不会被打断,但事务是为了保证能让一批指令一起按顺序执行。
  2. 事务相关指令

指令

作用

multi

开启事务

exec

执行事务队列中的指令,返回执行结果

watch

监视单个或多个key,若被监视的key被修改,则未完成的事务全部取消

unwatch

取消对所有key的监视

0 人点赞