Redis学习笔记——事务

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012525096/article/details/82854981

概述

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

特性

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

常用命令及场景模拟

常用命令

  1. DISCARD:取消事务,放弃执行事务块内的所有命令。
  2. EXEC:执行所有事务块内的命令。
  3. MULTI:标记一个事务块的开始。
  4. UNWATCH:取消WATCH命令对所有key的监视。
  5. WATCH key [key ...]:监视一个或多个key,如果在事务执行之前这个(些)key被其他命令所改动,那么事务将被打断。

场景模拟

正常执行

在这里插入图片描述
(1)MULTI,开启事务。
(2)执行各个语句,加入到队列,返回QUEUED
(3)EXEC,执行事务,返回每个语句的返回值。

放弃事务

在这里插入图片描述
(1)MULTI,开启事务。
(2)执行各个语句,加入到队列,返回QUEUED
(3)DISCARD,放弃事务,以上的所有语句都不会执行,放弃该事务块。

全体连坐

在这里插入图片描述
(1)MULTI,开启事务。
(2)执行各个语句,加入到队列,返回QUEUED
(3)执行错误语句,提示错误。
(4)EXEC,执行事务,提示事务被放弃因为有错误。
结果:所有的语句块都不会被执行,事务被放弃。

冤头债主

在这里插入图片描述
(1)MULTI,开启事务。
(2)执行各个语句,加入到队列,返回QUEUED
(3)EXEC,执行事务,错误语句返回错误信息,正常语句正常执行。
结果:错误的执行返回错误信息,其他的语句都会正常执行。
与全体连坐的区别:连坐的场景是,输入语句,即返回错误信息(不是加入队列),而冤头债主则是返回加入队列,全体连坐相当于编译错误(无法执行),冤头债主相当于运行时错误(某语句执行出错)。

Redis对事务的支持:部分支持,没有保持强一致性。

WATCH监控

悲观锁

悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边用到了很多这种锁的机制,比如行锁、表锁等,读锁,写锁等,都是在做操作之前先上锁。

乐观锁

乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。
乐观锁策略:提交版本必须大于记录当前版本才能执行更新。
典型的例子:Git、Svn,若远端已经有修改(新版本),则必须先拉取才能在提交修改。

场景模拟

在这里插入图片描述
(1)设置balance100。
(2)设置debt0。
(3)监视balance。
(4)开启事务。
(5)吃面条,balance-20。
(6)吃面条,debt+20。
(7)执行事务,成功。
(8)监视balance。
(9、10)别人设置balance800。
(11)开始事务。
(12)吃面条,balance-20。
(13)吃面条,debt+20。
(14)执行事务,返回nil,失败。
(15)发现出错,说明balance已经变动,查看,发现变动。
再次说明概念:WATCH KEY [KEY ...],监视一个或多个key,如果在事务执行之前,这个(些)key被其他命令所改动,那么EXEC执行事务将被打断,类似于乐观锁。
UNWTACH,放弃所有的key监控。

三阶段

开启:以MULTI开始一个事务。
入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列中。
执行:由EXEC命令触发事务。

三特性

(1)单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
(2)没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头疼的问题。
(3)不保证原子性:Redis同一个事务中如果有一条命令执行失败,其后的命令仍然被执行,没有回滚,即部分一致性。

猜你喜欢

转载自blog.csdn.net/u012525096/article/details/82854981
今日推荐