zoukankan      html  css  js  c++  java
  • Redis

    一、概述


    和传统关系型数据库一样,Redis 同样是支持事务的。Redis 的事务可以通过 MULTI/EXEC/DISCARD/WATCH 等命令来实现。

     

    二、事务的 ACID 特性


    1). 原子性:事务中的命令要么全部执行,要么都不执行。

    Redis 的事务和传统的关系型数据库事务最大的区别在于:Redis 事务不支持回滚,即使事务队列中某个命令执行期间出现了错误,整个事务也会继续执行下去,知道事务队列中所有命令执行完毕。

    那么不支持回滚对 Redis 来说有何优势:不需要支持回滚,Redis 内部可以保证简单而快速。

    不支持回滚是否合理:合理,事务队列中的命令在执行过程中,只会因为命令错误的语法而失败,而失败的命令是编程造成的,这些错误应该在开发过程中被发现,而不应该出现在生产环境中。

    2). 一致性:数据库在事务执行之前是一致的,在事务执行后无论事务执行成功还是失败,数据库都应该是一致的。

    “一致” 指的是数据符合数据库本身的定义和要求,没有非法或者无效的错误数据。Redis 通过谨慎的错误检测和简单的设计保证事务的一致性(详看本页:四)

    3). 隔离性:各个事务之间不会相互影响,在并发状态下和在串行状态下执行事务的结果完全相同。 

    4). 持久性:当事务执行完毕后,结果保存到数据库中不会丢失。

    • 无持久化机制下,事务部具有持久性:服务器停机重启后数据丢失。
    • RDB 机制下,在特定条件下才会保存数据集快照,不能保证数据在第一时间被保存在硬盘中。
    • AOF 机制下,appendfsync = always 时,程序总会在执行命令之后调用同步函数,将命令数据存在硬盘中,这种情况下的事务具有持久性。
    • AOF 机制下,appendfsync = everysec 时候,程序会每秒同步一次数据到硬盘。因为停机可能就发生在命令执行完毕但是尚未同步的那一秒钟内,这样会造成事务数据丢失,故而不具有持久性。
    • AOF 机制下,appendfsync = no,由操作系统决定何时将数据同步到硬盘。因为事务数据可能在等待同步的过程中丢失,这样会造成事务数据丢失,故而不具有持久性。

     

    三、相关命令的用法


    1). MULTI 与 EXEC:MULTI 用于开启事务,总是返回 ok。MULTI 执行后,后面的命令暂时不会执行,而是会存到队列中,等到 EXEC 执行之后,队列中的命令才会依次序执行。例子如下:

    2). DISCARD 始终返回 ok,会清空事务队列,并且放弃执行事务。例子如下:

    3). WATCH 命令(想看本页:五)

     

    四、Redis 怎样处理事务中的错误


    Redis 怎样处理事务中的错误来保证数据库的 “一致性” :

    1). 入队错误

    可能原因:命令不存在,命令格式不正确等

    处理方式:Redis 会对入队失败的命令进行记录,当调用 exec 的时候,自动拒绝执行并放弃这个事务。

    例子如下:INCR mykey 1 入队失败,因为命令格式不正确。

    2). 执行错误

    可能原因:命令语法错误(入队时无法检测,只有在执行的时候才会报错,比如事务中处理集合的命令用在了字符串上面)。

    处理方式:事务中的命令执行失败,继续执行下一条命令,直至事务队列中的命令执行结束。

    例子如下:LPOP mykey 报错,作用于 list 类型,不能用于字符串;但是不影响后续命令执行,+1 操作依然执行成功。

    3). 服务器停机

    • 如果服务器运行在无持久化的模式下,那么重启后的数据库是空白的,空白的数据库总是一致的。
    • 如果服务器运行在 RDB 模式下,可以利用现有的 RDB 文件还原数据库到一个一致的状态。若 RDB 文件找不到,那么重启后的数据库是空白的,空白的数据库总是一致的。
    • 如果服务器运行在 AOF 模式下,可以根据现有的 AOF 文件来恢复数据,将数据库还原到一个一致的状态。若 AOF 文件找不到,那么重启后的数据库是空白的,空白的数据库总是一致的。

    综上所述,服务器停机不会影响数据库一致性。

     

    五、WATCH 命令与乐观锁


    WATCH 命令的返回值总是为 ok。

    WATCH 命令本身就是一个乐观锁,它可以在 EXEC 命令执行之前,监视一定数量的 key,并在 EXEC 执行时,检查这些 key 是否被修改过,如果是的话,服务器就拒绝执行事务。例子如下:

    时间 客户端A 客户端B
    T1 WATCH  name  
    T2 MULTI  
    T3 SET  name  aa  
    T4   SET  name  bb
    T5 EXEC  

    客户端 A 执行事务的时候发现 name 的值被修改了,所以服务器拒绝执行这个事务。

     

    如何取消对 key 的监视:

    • WATCH 对 key 的监视从调用 WATCH 开始生效,直到调用 EXEC 为止。EXEC 被调用的时候不管事务是否执行,都会取消对 key 的监视。
    • 另外当客户端断开连接后也会取消监视。
    • 使用无参数的 UNWATCH 可以取消对所有 key 的监视。

     

     

     

  • 相关阅读:
    Hdu 5396 Expression (区间Dp)
    Lightoj 1174
    codeforces 570 D. Tree Requests (dfs)
    codeforces 570 E. Pig and Palindromes (DP)
    Hdu 5385 The path
    Hdu 5384 Danganronpa (AC自动机模板)
    Hdu 5372 Segment Game (树状数组)
    Hdu 5379 Mahjong tree (dfs + 组合数)
    Hdu 5371 Hotaru's problem (manacher+枚举)
    Face The Right Way---hdu3276(开关问题)
  • 原文地址:https://www.cnblogs.com/xmsx/p/5387027.html
Copyright © 2011-2022 走看看