【Redis】详解事务

什么是事务?简单点说事务就是一次批处理,给定脚本一下性执行完毕

什么是事务

在这里插入图片描述

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

作用

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

命令
  1. 取消事务
DISCARD
  1. 执行所有事务块的命令
EXEC
  1. 开启事务,标记一个事务的开始
MULTI
  1. 取消WATCH命令对所有key的监视
UNWATCH
  1. 监视一个或多个key,如果在事务执行之前这个key被其他命令修改,那么事务将被打断
WATCH key [key......]
特点

正常情况,multi正常开启事务,然后输入一条一条的set、get命令入队,最后exec执行,输出正确结果,

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1 
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) "v1"
127.0.0.1:6379> 

放弃事务,在exec之前输入discard,事务就会被放弃,事务的命令都不会执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1 
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> 

全体连坐,要么全部成功,要么全部失败,只要有一个失败,就全部不执行。限于在入队时就报错。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1 
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> setget k1 v1
(error) ERR unknown command 'setget'
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> 

冤头债主,谁犯错谁承担,如果入队没有报错,那么在执行时,谁报错谁失败,不会影响别的命令

127.0.0.1:6379> keys *
1) "k2"
2) "k1"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr k1
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range
2) OK
127.0.0.1:6379> get k3
"v3"
127.0.0.1:6379> 

watch监控,类似于乐观锁,如果但是一个key,那么如果有另一个客户端修改监视的key之后,本客户端再修改就会失败,只能重新监视,然后执行

127.0.0.1:6379> keys *
1) "dbt"
2) "balance"
127.0.0.1:6379> get balance
"100"
127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> set balance 500
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby balance 10
QUEUED
127.0.0.1:6379> incrby dbt 10
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> 

悲观锁
悲观地认为一定会有人改自己的数据,所以每次操作之前把整张表都锁上

乐观锁
行锁,每次拿数据都认为别人不会修改,但是有一个版本号

exec,discard,unwatch命令都会清除连接中的所有监视。

小结

  • 单独的隔离操作:事务中的所有命令都会被序列化,按顺序的执行,执行过程中不会被其他客户端发送来的命令请求打断
  • 没有隔离级别的概念,队列中的命令在提交之前不会执行
  • 不保证原子性,无回滚

猜你喜欢

转载自blog.csdn.net/yujing1314/article/details/106105482