Chapter4 Redis事务

4.1 Redis 的事务

4.1.1 事务简介

  1. Redis 的事务允许在一次单独的步骤中执行一组命令,并且能够保证将一个事务中的所有命令序列化,然后按顺序执行;
  2. 在一个 Redis 事务中, Redis 要么执行其中的所有命令,要么什么都不执行,即 Redis 的事务要能够保证序列化和原子性。

4.1.2 事务的错误处理

  1. 组队中某个命令出现报告错误:整个队列被取消
  2. 执行阶段某个命令报错:该命令不执行,其它命令会被执行,不回滚

4.2 Redis 事务的常用命令

4.2.1 multi

  1. 用于标记事务块的开始。 Redis 会将后续的命令逐个放入队列中,然后才能使用 EXEC 命令原子化地执行这个命令序列

  2. 示例

    开启事务

    127.0.0.1:6379> multi
    OK

    添加

    127.0.0.1:6379> set s1 v1q
    QUEUED
    127.0.0.1:6379> get s1
    QUEUED

4.2.2 exec

  1. 在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态

  2. 返回一个数组,其中的每个元素分别是原子化事务中的每个命令的返回值

  3. 示例

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s1 vps
    QUEUED
    127.0.0.1:6379> get s1
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) "vps" 

4.2.3 discard

  1. 清除所有先前在一个事务中放入队列的命令,并且结束事务

  2. 如果使用了 WATCH 命令,那么 DISCARD 命令就会将当前连接监控的所有键取消监控

  3. 示例

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s1 watch
    QUEUED
    127.0.0.1:6379> discard
    OK
    127.0.0.1:6379> exec
    (error) ERR EXEC without MULTI

    4.2.4 watch

  4. 语法

    watch key [key...]
  5. 监控键值:

    • 如果被监控的 key 值在本事务外有修改时,则本事务所有指令都不会被执行
    • Watch 命令相当于关系型数据库中的乐观锁
  6. 示例

    127.0.0.1:6379> watch s1
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s1 watch
    QUEUED
    127.0.0.1:6379> strlen s1
    QUEUED
    127.0.0.1:6379> get s1
    QUEUED
    # 启动另一个客户端,修改s1
    # 127.0.0.1:6379> set s1 s111
    # OK
    127.0.0.1:6379> exec
    (nil)

4.2.5 unwatch

  1. 清除所有先前为一个事务监控的键
  2. 如果在 watch 命令之后调用了 EXEC 或 DISCARD 命令,那么就不需要手动调用 UNWATCH 命令

4.3 Redis 三特性

4.3.1 单独的隔离操作

  1. 事务中的所有命令都会序列化、顺序地执行
  2. 事务在执行过程中, 不会被其它客户端发来的命令请求所打断,除非使用 watch 命令监控某些键

4.3.2 没有隔离级别的概念

  1. 队列的命令提交前不会被执行
  2. 因为未执行任何命令,自然也不存在脏读等问题

4.3.3 不保证事务的原子性

  1. redis 同一个事务中如果一条命令执行失败,其后的命令仍然可能会被执行, redis 的事务没有回滚
  2. Redis 已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为 Redis 不需要事务回滚的能力