Redis 事务

文章目录

  • 一、事务的定义
  • 二、事务的基本操作
  • 三、事务的错误处理注意事项
    • 3.1 组队阶段
    • 3.2 执行阶段
  • 四、Redis 事务的三特性
  • 五、锁
    • 5.1 监视锁
    • 5.2 分布式锁
    • 5.3 分布式锁改良-1
    • 5.4 分布式锁改良-2
  • 参考文章


一、事务的定义

Redis 的事务就是一个命令执行的队列,将一系列的预定义命令放入队列;执行时按照添加顺序执行,中间不会被打断和干扰。

  • 一个队列中,一次性、顺序性、排它性地执行一系列的命令;
  • redis 的事务更像是批量执行指令。

二、事务的基本操作

1、multi:开启事务,并且将后续的指令均加入到事务(命令队列)中;
2、exec:执行事务,redis 将依次执行命令队列中的命令;
3、discard:取消事务,在开启事务之后,执行事务之前。

注意:加入事务的命令只是暂时存放在队列中,只有在执行了 exec 指令后才会被执行。


三、事务的错误处理注意事项

3.1 组队阶段

组队阶段中某个命令出现错误,执行时整个命令队列都会被取消
Redis 事务_第1张图片

3.2 执行阶段

执行阶段,如果某个命令出现了错误,那么只有报错的命令不会被执行,而其它命令都会被执行,不会回滚
Redis 事务_第2张图片
**


四、Redis 事务的三特性

1、单独的隔离操作:事务中所有命令都会被序列化、按顺序的执行。事务在执行的过程中,不会被其它客户端发来的命令请求所打断。
2、没有隔离级别的概念:命令队列在提交之前都不会被执行。因为事务提交前没有命令会被执行,所以不存在“事务内的查询可以看到事务内的更新,而事务外的查询不能看到”这种情况。
3、不保证原子性:一个事务中即时有命令执行失败,其它命令也会正常执行,不会回滚。


五、锁

5.1 监视锁

  • 添加监视锁:在 multi 之前对 key 添加监视锁,在执行 exec 之前如果这个 key 被其它命令所修改,那么事务会被打断
watch key1 [key2...]
  • 取消监视锁:在 discard / exec 之前取消对所有 key 的监视
unwatch

5.2 分布式锁

我们可以使用 setnx 指令设置分布式锁

setnx lock-key value

setnx 指令会有返回值,返回 1 则成功;返回 0 则失败。

  • 若成功,表明获得到锁,进行下一步业务操作;
  • 若失败,表明未获得锁,排队或等待。

操作完成后通过 del 来释放锁。

5.3 分布式锁改良-1

1、分布式锁的问题
若某个客户端获得到锁之后发生了宕机,导致锁无法被释放。如下图所示:
Redis 事务_第3张图片
Redis 事务_第4张图片
Redis 事务_第5张图片

2、解决方案
我们可以在 setnx 指令的基础上再使用 expire 来添加过期时间,若到了时间还未释放锁,则使锁失效。

expire lock-key second
pexpire lock-key millisecond

Redis 事务_第6张图片

5.4 分布式锁改良-2

1、分布式锁改良-1的问题
若某个客户端获得锁之后,还没来得及设置过期时间就宕机了,导致锁无法被释放。如下图所示:
Redis 事务_第7张图片

2、解决方案
我们可以使用 LUA 脚本,可以使获取锁和设置过期时间这两步操作变为一个原子性操作,要么全部成功,要么全部失败。
Redis 事务_第8张图片

参考文章

  • https://www.bilibili.com/video/BV1CJ411m7Gc

你可能感兴趣的:(Redis,redis)