Redis_事务

Redis的事务可以一次性执行多条命令,本质是一组命令的集合,一个事务中的命令都会序列化,在执行的时候,会按顺序的串行执行,不允许加塞,不会被其他的命令插入。在一个事务的命令队列中,一次性,顺序性、排他性的执行一系列的命令。

Redis事务命令

  1. MULTI:标记一个事务块的开始。
  2. EXEC:执行事务中所有在排队等待的指令并将链接状态恢复到正常,当使用WATCH时,只有当被监视的键没有被修改,且允许检查设定机制时,EXEC会被执行。
  3. DISCARD:放弃事务,并且将连接状态恢复到正常。如果已使用WATCH,DISCARD将释放所有被WATCH的key。
  4. WATCH key [key ...]:标记所有指定的key 被监视起来,在事务中有条件的执行(乐观锁check-and-set [CAS] )。如果被监视的key被其他的命令改动,那么事务将打断,不会执行成功。
  5. UNWATCH:释放一个事务中已被监视的所有key。如果执行EXEC 或者DISCARD, 则不需要手动执行UNWATCH 。

事务正常执行

127.0.0.1:6379> MULTI               # 标记事务开始
OK
127.0.0.1:6379> SET money 100       # 添加命令
QUEUED                              # 命令进入队列中等待执行
127.0.0.1:6379> SET name zhangsan
QUEUED
127.0.0.1:6379> SET gender male
QUEUED
127.0.0.1:6379> EXEC                # 执行事务,三条命令顺序执行
1) OK
2) OK
3) OK
127.0.0.1:6379> KEYS *
1) "gender"
2) "money"
3) "name"
127.0.0.1:6379> GET name
"zhangsan"

放弃事务

127.0.0.1:6379> MULTI               # 标记事务开始
OK
127.0.0.1:6379> SET name zhangsan   # 添加命令
QUEUED                              # 命令进入队列中等待执行
127.0.0.1:6379> SET gender male
QUEUED
127.0.0.1:6379> DISCARD             # 放弃事务
OK
127.0.0.1:6379> KEYS *              # 可以看到,刚才队列中的命令并没有被执行
(empty list or set)

事务中语法错误

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET name zhangsan
QUEUED
127.0.0.1:6379> SET age 20
QUEUED
127.0.0.1:6379> asdas       # 故意乱输命令
(error) ERR unknown command `asdas`, with args beginning with: 
127.0.0.1:6379> SET gender male
QUEUED
127.0.0.1:6379> exec        # 在执行事务的时候,抛出错误,并且其他正常的命令都没有执行成功
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> KEYS *
(empty list or set)

事务中命令执行失败

127.0.0.1:6379> SET name zhangsan       # 在事务之前设置一个name值
OK
127.0.0.1:6379> MULTI                   # 开始事务
OK
127.0.0.1:6379> SET age 20
QUEUED
127.0.0.1:6379> INCRBY name 20          # 对name增加20
QUEUED
127.0.0.1:6379> SET address cd
QUEUED
127.0.0.1:6379> exec                    # 执行事务后,发现对name增加20的命令抛出错误,但是其余两条命令却执行成功了
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
127.0.0.1:6379> GET age
"20"

在事务中,可能发生两种错误

  1. 语法错误:这种在命令放入队列之前就可以检测出来的错误,就会直接终止事务的继续,其他命令也将不会被执行成功。
  2. 执行失败:执行失败的命令,比如INCR命令,它只对数字的值生效,不然就会抛出错误,但是在命令入队的时候,是检测不出来的。所以事务中的其他命令依旧会执行成功。

监视

第一个客户端

127.0.0.1:6379> set money 200
OK
127.0.0.1:6379> WATCH money     # 监视 money
OK
127.0.0.1:6379> MULTI           # 开始事务
OK
127.0.0.1:6379> INCRBY money 20
QUEUED
127.0.0.1:6379> INCRBY money 20
QUEUED
127.0.0.1:6379> EXEC            #执行事务
(nil)

第二个客户端

127.0.0.1:6379> SET money 300   # 在第一个客户端执行事务之前,第二个客户端修改了money的值,事务不会执行成功
OK

WATCH 指令,类似乐观锁,事务提交时,如果被监视的key已经在其他地方被修改,那么整个事务队列的命令都不会被执行。

放弃监视

如果监视了key,那么在 MULTI 标记事务之前,执行了 UNWATCH ,那么将释放一个事务中已被监视的所有key。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值