• 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 的监视。

     

     

     

  • 相关阅读:
    文件上传之 MultipartFile
    EL表达式从数组 Map List集合取值
    Servlet监听器
    分页技术框架(Pager-taglib)学习三(pager-taglib中传递参数时中文乱码问题)
    分页技术框架(Pager-taglib)学习二(SSH数据库分页)
    分页技术框架(Pager-taglib)学习一(页面分页)
    从request获取各种路径总结
    jsp的页面包含——静态包含、动态包含
    Java对象的浅克隆和深克隆
    Java序列化与反序列化学习(三):序列化机制与原理
  • 原文地址:https://www.cnblogs.com/xmsx/p/5387027.html
Copyright © 2020-2023  润新知