修改器内存写入失败_Redis 事务,以及事务失败的处理

事务命令

  1. Redis事务,会将所有命令放入一个命令队列中,再由队列中执行命令。
  2. 事务的命令分为:
  • MULTI 开始事务---->各种命令操作,SET,GET,SADD等等(每一步操作后,会显示QUEUED,表示已经入队命令队列)---->EXEC执行命令队列
  • DISCARD:取消一个事务,清空事务命令队列,客户端调整为非事务状态
  • WATCH:在进入事务之前执行,监听任意数量的key,当调用EXEC时,如果这个key被其他用户修改了,那么事务不在执行,返回失败。
  • 以下示例展示了一个执行失败的事务例子:

redis> WATCH name

OK

redis> MULTI

OK

redis> SET name peter

QUEUED

redis> EXEC (nil)

以下执行序列展示了上面的例子是如何失败的:

时间 客户端 A 客户端 B

T1 WATCH name

T2 MULTI

T3SET name peter

T4 SET name john

T5EXEC

在时间 T4 ,客户端 B 修改了 name 键的值, 当客户端 A 在 T5 执行 EXEC 时,Redis 会发现 name 这个被监视的键已经被修改, 因此客户端 A 的事务不会被执行,而是直接返回失败。


ACID

Redis 的事务保证了 ACID 中的一致性(C)和隔离性(I),但并不保证原子性(A)和持久性(D)。

1.原子性(一个事务所有操作要么全部成功,要么全部失败)

redis的单个命令是原子性的,但是事务中的的redis命令,就算后面的命令失败/终止了(比如KILL进程,主机宕机等),此时事务失败,前面执行的命令也不会回滚。

2.一致性

(1)不正确入队命令的事务不会被执行,不会影响数据库的一致性

(2)命令执行中的错误,将错误包含在事务结果中,不会中断事务,不影响已执行结果,也不影响后面命令的执行,对事务的一致性也没有影响。

(3)进程终结

  • 内存模式:如果 Redis 没有采取任何持久化机制,那么重启之后的数据库总是空白的,所以数据总是一致的。
  • RDB 模式:在执行事务时,Redis 不会中断事务去执行保存 RDB 的工作,只有在事务执行之后,保存 RDB 的工作才有可能开始。所以当 RDB 模式下的 Redis 服务器进程在事务中途被杀死时,事务内执行的命令,不管成功了多少,都不会被保存到 RDB 文件里。恢复数据库需要使用现有的 RDB 文件,而这个 RDB 文件的数据保存的是最近一次的数据库快照(snapshot),所以它的数据可能不是最新的,但只要 RDB 文件本身没有因为其他问题而出错,那么还原后的数据库就是一致的。
  • AOF 模式:因为保存 AOF 文件的工作在后台线程进行,所以即使是在事务执行的中途,保存 AOF 文件的工作也可以继续进行,因此,根据事务语句是否被写入并保存到 AOF 文件,有以下两种情况发生:
    1)如果事务语句未写入到 AOF 文件,或 AOF 未被 SYNC 调用保存到磁盘,那么当进程被杀死之后,Redis 可以根据最近一次成功保存到磁盘的 AOF 文件来还原数据库,只要 AOF 文件本身没有因为其他问题而出错,那么还原后的数据库总是一致的,但其中的数据不一定是最新的。
    2)如果事务的部分语句被写入到 AOF 文件,并且 AOF 文件被成功保存,那么不完整的事务执行信息就会遗留在 AOF 文件里,当重启 Redis 时,程序会检测到 AOF 文件并不完整,Redis 会退出,并报告错误。需要使用 redis-check-aof 工具将部分成功的事务命令移除之后,才能再次启动服务器。还原之后的数据总是一致的,而且数据也是最新的(直到事务执行之前为止)。

3.隔离性

Redis 是单进程程序,并且它保证在执行事务时,不会对事务进行中断,事务可以运行直到执行完所有事务队列中的命令为止。因此,Redis 的事务是总是带有隔离性的。

4.持久性

由redis的持久化模式决定:

  • 内存模式-无持久化
  • RDB-服务器可能在事务执行之后、RDB 文件更新之前的这段时间失败,所以 RDB 模式下的 Redis 事务也是不持久的。
  • AOF-后台每秒fsync策略,不是主线程阻塞执行,如果在保存时宕机,可能有一秒数据丢失,也非持久的。

你可能感兴趣的:(修改器内存写入失败)