Redis事务

redis的事务

redis事务是mysql事务的弱化版本

  • 原子性:redis会把多个操作打包在一起,要么全部都执行,要么全部都不执行。而mysql的原子性,会保证打包的多个操作,要么全部执行成功,要么全部都不执行,如果事务中有操作失败的,会进行回滚
  • 不具备一致性:redis没有约束,也没有回滚机制,事务执行的过程中如果某个修改操作出现失败,就可能引起不一致的情况。
  • 不具备持久性:redis是内存数据库,数据是存储在内存上,虽然redis也有持久化机制,但是是否开启持久化,是redis服务器自己的事情,和事务没有直接关系
  • 不需要隔离性:redis是单线程的服务器程序,所有的请求/事务,都是“串行”执行,不涉及多线程。

redis如何实现事务

redis实现事务,给每个客户端引入一个队列。开启事务的时候,此时客户端输入的命令,就会发送给服务器并且进入这个队列,但不是立即执行。而是当遇到“执行命令”命令的时候,此时就会把队列中的任务都按照顺序依次执行。

事务的应用场景

秒杀场景
Redis事务_第1张图片

事务操作

  1. 开启事务:multi命令
  2. 执行事务:exec命令,真正执行exec命令,客服端才会真正把操作发送给服务器

Redis事务_第2张图片

  1. 放弃事务:discard命令,放弃当前事务,直接清空事务队列,之前的操作都不会执行

Redis事务_第3张图片

  1. 监视key:watch key [key...]命令,在执行事务的时候,如果某个事务中修改的只,被别的客服端修改了,此时就容易出现数据不一致的问题。

Redis事务_第4张图片
如图所示过程,从输入命令的时间看,是客服端1先执行set key4 444,客服端2后执行set key4 444444444.但从实际执行时间看,是客服端2先执行,客服端1后执行。这个时候就会引起歧义,redis无法保证隔离性,但至少要告诉用户,当前操作有风险。因此引入了watch命令,可以监控一组具体的key
Redis事务_第5张图片
在上图中,watch监控key5,在事务执行之前,另外一个客服端修改了key5,于是在exec执行该事务时,set key5 555没有被执行,返回nil。

watch实现原理

watch的实现,类似于“乐观锁”。

预期“锁冲突”不高

watch是基于“版本号”这样的机制,来实现“乐观锁”。如下图所示:
Redis事务_第6张图片
:::info
watch的本质就是给exec加一个判定条件
:::

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