Redis事务

young 529 2021-10-18

特点:

  1. 顺序执行,先添加的先执行,后添加的后执行
  2. 不会受到其他客户端的干扰

命令

multi开启事务

没有子事务,没有嵌套事务

exec 执行事务

discard 取消事务

watch 乐观锁

unwatch 取消监视

事务演示

ada和bob各有1000元,ada需要向bob转账100元

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set ada 1000
OK
127.0.0.1:6379> set bob 1000
OK
# 开启事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby ada 100
# 进入事务队列
QUEUED
127.0.0.1:6379> incrby bob 100
QUEUED
# 执行事务
127.0.0.1:6379> exec
1) (integer) 900
2) (integer) 1100

开启事务之后,客户端向服务端发送命令,服务端不会马上执行,而是放在一个队列中,执行exec命令后,才会按照命令入队的顺序执行

watch指令

客户端1

127.0.0.1:6379> set balance 1000
OK
# 监视balance
127.0.0.1:6379> watch balance
OK
# 开启事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby balance 100
QUEUED

此时,客户端2执行

127.0.0.1:6379> decrby balance 100
(integer) 900

再在客户端1执行

127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get balance
"900"

此时事务执行失败

事务可能遇到的问题

执行exec之前

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set qs 2673
QUEUED
127.0.0.1:6379> hset qs 2673
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> 

事务会取消

执行exec之后

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 1
QUEUED
127.0.0.1:6379> hset k1 a b
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get k1
"1"
127.0.0.1:6379> 

没有问题的命令提交成功了,异常的命令提交失败

所以redis的事务不具有原子性