zoukankan      html  css  js  c++  java
  • Redis入门(六)——Redis事务

    Redis入门(六)——Redis事务


     目录:

    • redis事务简介
    • redis事务的使用
    • 小结

    1.redis事务简介

    事务指的是可以一次执行多个命令,本质是一组命令集合,一个事务中的所有命令都会序列化,按顺序的串行化执行而不会被其他命令插入。银行转账就是最经典的事务场景之一。

    redis事务用于一个队列中,一次性,顺序性。排他性的执行一系列命令。

    传统的关系型数据库如mysql,oracle中的事务需要满足ACID四个特性。即:

    原子性(atomicity):事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于其数据修改,要么全部执行,要么全部不执行。
    一致性(consistency):事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。
    隔离性(isolation)一个事务的执行不能被其他事务所影响。

    持久性(durability):一个事务一旦提交,事物的操作便永久性的保存在DB中。即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

    而redis数据属于典型的Nosql数据库。不需要满足ACID四个特性。Nosql数据库满足CAP三个特性其中之二。CAP即:

    强一致性(Consistency):在任意时刻,所有的分布式节点中的数据是一样的。

    可用性(Availability):分布式系统中某一个服务在某台或者多台台服务器出问题后,在其他服务器上依然能够完成用户的操作。

    分区容错性Partition torerance):在出现网络分区(比如断网)的情况下,分离的系统也能正常运行。

    2.redis事务使用

    下表列出了 redis 事务的相关命令:

    命令 描述 用法
    MULTI 标记一个事务块的开始

    MULTI

    标记一个事务开始,后面是一系列事务操作。

    EXEC 执行所有事务块内的命令

    EXEC

    在一系列事务操作后使用该命令,执行所有事务块内的命令。

    DISCARD 取消事务,放弃执行事务块内的所有命令

    DISCARD

    在一系列事务操作后使用该命令,放弃执行事务块内的所有命令

    WATCH 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

    WATCH key [key ...]

    UNWATCH 取消 WATCH 命令对所有 key 的监视。 UNWATCH

    MULTI命令实例:

     只要符合redis语法规范的命令均可入队。

    放弃事务实例:

    事务执行失败实例:

     当事务中有一个命令执行失败,其他命令会执行成功吗?下图为实际操作的实例:

    可见,redis事务中要么全部执行成功,要么全部执行失败。可是前文不是说不满足原子性吗,这里岂不是满足原子性。上图中出现了我胡乱加的一个命令abc k7 v7,也就是说该命令不满足redis语法规范。那如果是满足redis语法规范的语句,在redis事务中执行失败,其他合法命令会怎么样呢?下图演示了该场景下的操作情况。

     其中,k1是一个string类型的数据,执行incr命令会不通过,但是由于符合语法规范,该语句不会报错,仍然显示加入队列中。当我们执行EXEC命令来执行整个事务的时候后,可见incr k1执行失败,而其他可以执行的语句并不受影响。可见redis事务不满足原子性。

    WATCH监控:

    在介绍WATCH命令之前先说明下redis中的乐观锁悲观锁的概念以及CAS。

    悲观锁:每次器拿数据的时候都认为该数据会被修改,所以每次拿到数据后都会对该数据上锁,保证自由自己操作该数据。等本次获取的锁释放后其他操作方可获得该锁。

    乐观锁:每次器拿数据的时候都认为该数据不会被修改,所以不会上锁,但是下更新该数据的时候回判断下别人有没有更新该数据,通常使用版本号的机制。即每次修改数据后对该数据价格版本号,其他人在修改该数据前先对比下该数据的版本号有没有变化。一般实际场景中使用的是乐观锁。

    下面以信用卡可用余额与欠额的场景说明WATCH的应用。

    首先来看没有加塞的场景,WATCH balance,然后在一个事务中减少balance增加debt,执行EXEC命令后,可见事务执行成功。

     再来看有加塞的场景,首先还是WATCH balance,然后另外开启一个redis连接。修改balance的值,再回到第一个redis连接上,执行之前的事务操作,该事务操作是否会执行成功,请看下面的操作实例

     UNWATCH命令:

    执行UNWATCH,取消 WATCH 命令对所有 key 的监控。注意,一旦执行了EXEC命令,之前加的监控锁都会被取消。

    3.小结

    WATCH指令类似于乐观锁,事务提交时,如果key的值已经被别的客户改变,比如某个list已被别的客户端push/pop过了,整个事务都不会被执行。

    通过WATCH命令在事务执行之前监控了多个key,倘若在WATCH之后有任何key的值发生变化,EXEC命令执行的事务都将被放弃,同时返回Nullmuti-bulk应答已通知调用者事务执行失败。

  • 相关阅读:
    Fastjson
    react 使用createContext、Consumer 及 useContext 、Class.contextType父子组件共享数据
    使用useReducer 实现 todoList
    react中 useMemo与useCallback使用
    react17 函数组件 使用 better-scroll2.0 封装方法 及 使用
    react 执行 yarn build ,无法直接打开dist文件下的index
    react-redux 持久数据存储
    document.body.removeChild 获取到 symbol 标签
    react嵌套路由,并设置默认子路由
    Vagrant环境下配置node_exporter、mysqld_exporter、prometheus、grafana
  • 原文地址:https://www.cnblogs.com/zylhxd/p/11439247.html
Copyright © 2011-2022 走看看