【Redis】Redis事务

目录

  • MySQL事务
  • Redis事务
    • 弱化的原子性
    • 不保证一致性
    • 不具备持久性
    • 不涉及隔离性
  • Redis事务使用场景
  • Redis的事务为啥就搞得这么简单~为什么不设计成和MySQL一样强大?
  • Redis事务相关命令
    • 开启事务 MULTI
    • 执行事务 EXEC
    • 放弃当前事务 DISCARD
    • WATCH 监控某个key是否在事务执行之前,发送了改变
      • watch的实现原理

MySQL事务

原子性:把多个操作,打包成一个整体了
一致性:事务执行之前,和之后,数据都不能离谱
持久性:事务中做出的修改都会存硬盘
隔离性:事务并发执行,涉及到的一些问题~

Redis事务

弱化的原子性

原子性:Redis的事务到底有没有原子性?存在争议!
最原本的含义,是把多个操作打包到一起,要么全部都执行(不保证成功),要么全都不执行~
Redis做到了上述的含义~
但是MySQL这里的原子性,走的更远,也是把多个操作打包到了一起,要么全部执行成功,要么全都不执行。

redis如果事务中若干个操作,存在有失败的,就失败吧。
MySQL如果事务中有操作执行是啊比,要进行回滚!把中间已经执行的操作,全都回退了~

不保证一致性

redis没有约束,也没有回滚机制,事务执行过程中如果某个修改操作出现失败,就可能引起不一致的情况。

不具备持久性

redis本身就是内存数据库,数据是存储再内存中的。虽然redis也有持久化机制~
但是这里的持久化机制,和事务没有啥直接关系~

不涉及隔离性

Redis是一个单线程模型的服务器程序,所有的请求/事务,都是“串行”执行的~

Redis事务使用场景

Redis的事务,主要的意义,就是为了“打包”,避免其他客户端的命令,插队插到中间~
Redis中实现事务,是引入了队列
开启事务的时候,此时客户端输入的命令,就会发给服务器并且进入这个队列中(并不是立即执行)
当遇到了“执行事务”命令的时候,此时就会把队列中的这些任务都按照顺序依次执行~
主线程会把事务中的操作都执行完,再执行别的客户端。

Redis的事务为啥就搞得这么简单~为什么不设计成和MySQL一样强大?

MySQL的事务,在背后付出了很大的代价~
空间上,要花费更多的空间来存储更多的数据.
时间上,也要有更大的执行开销。
正是因为MySQL上述的问题,才有了Redis上场的机会~

Redis事务相关命令

开启事务 MULTI

【Redis】Redis事务_第1张图片
在服务器的事务队列中,保存了上述请求。
此时如果另外开一个客户端,再尝试查询这几个key对应的数据,是查不到的。
【Redis】Redis事务_第2张图片

执行事务 EXEC

【Redis】Redis事务_第3张图片

【Redis】Redis事务_第4张图片

放弃当前事务 DISCARD

【Redis】Redis事务_第5张图片
在这里插入图片描述
当开启事务,并且给服务器发送若干个命令之后,此时服务器重启~此时的这个事务咋办?
此时的效果其实就等同于discard。

WATCH 监控某个key是否在事务执行之前,发送了改变

在这里插入图片描述

在这里插入图片描述
【Redis】Redis事务_第6张图片

在这里插入图片描述
【Redis】Redis事务_第7张图片
在这里插入图片描述
【Redis】Redis事务_第8张图片
在这里插入图片描述
在这里插入图片描述

watch的实现原理

watch的实现,类似一个“乐观锁”
乐观锁和悲观锁:不是指某个具体的锁,而是指的是某一类锁的特性

乐观锁:加锁之前,就有一个心理预期,预期接下来的锁冲突的概率比较低
悲观锁:加锁之前,就有一个心理预期,预期接下来的锁冲突的概率比较高

锁冲突概率高和冲突概率低,接下来要做的工作是不一样的~~

watch就相当于是基于版本号这样的机制,来实现了“乐观锁”

当执行watch key 的时候,就会给这个key安排一个版本号
版本号可以理解成一个“整数”
每次在修改的时候,版本号都会“变大”

【Redis】Redis事务_第9张图片
如果一致,说明当前key在事务开启到最终执行这个过程中,没有别的客户端修改
于是才能真正进行设置
如果不一致,说明key在其他客户端中改过了,因此此处就丢弃事务中的操作~
exec返回nil

你可能感兴趣的:(Redis,redis,数据库,缓存)