redis--事务

[TOC]

1. 介绍

  • 事务:
    1. 事务是一个单独的隔离操作:事务中的命令都会序列化,按顺序执行。事务在执行的过程中,不会被其他客户端发送的消息打断。
    2. 事务是一个原子操作:事务中的命令要么全部执行,要么全部不执行。
  • 命令:
    1. MULTI:事务开始的标记
    2. EXEC:执行事务中的命令
    3. DISCARD:刷新事务中的命令
    4. WATCH:标记key可能存在冲突,需要监视

2. 命令

2.1 MULTI

命令:==MULTI==

命令说明:事务的开始标记

返回值:OK

image-20200720193850376

2.2 EXEC

命令:==EXEC==

命令说明:事务执行。

返回值:执行结果。

image-20200720194019081

2.3 DISCARD

命令:==DISCARD==

命令说明:放弃事务。

返回值:OK

image-20200720194728486

2.4 WATCH

命令:==WATCH==

命令说明:监视key。在执行了WATCH之后,只要指定的key有操作,那么,在WATCH后面的exec之前的事务都不会执行。当执行了exec后,不管事务成功与否,都会去除监视。

image-20200720195040357

2.5 事务异常

  • 事务执行异常

==注意:事务中的命令执行异常不会阻止事务的执行。==

image-20200720194211724
  • 事务创建异常

==注意:事务中的命令如果出现语法异常,那么操作入队失败。==

image-20200720195415265

3. redis为什么不支持事务回滚

如果你有使用关系式数据库的经验, 那么 “Redis 在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。

以下是这种做法的优点:

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

有种观点认为 Redis 处理事务的做法会产生 bug , 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 INCR 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了 INCR , 回滚是没有办法处理这些情况的。

4. redis 持久化与事务

当使用 AOF 方式做持久化的时候, Redis 会使用单个 write(2) 命令将事务写入到磁盘中。

然而,如果 Redis 服务器因为某些原因被管理员杀死,或者遇上某种硬件故障,那么可能只有部分事务命令会被成功写入到磁盘中。

如果 Redis 在重新启动时发现 AOF 文件出了这样的问题,那么它会退出,并汇报一个错误。

使用redis-check-aof程序可以修复这一问题:它会移除 AOF 文件中不完整事务的信息,确保服务器可以顺利启动。

从 2.2 版本开始,Redis 还可以通过乐观锁(optimistic lock)实现 CAS (check-and-set)操作。

你可能感兴趣的:(redis--事务)