• Redis(1.3)Redis的基本特性(事务、多数据库)


    【1】两大特性

      (1)多数据库

          1个redis实例 可以有16个数据库,默认下标为0~15,默认连接到的是 0 下标的数据库。

      (2)事务

    【2】多数据库

      【2.1】概念

        1个redis实例 可以有16个数据库,默认下标为0~15,默认连接到的是 0 下标的数据库。

      【2.2】基本操作

        (1)select (切换数据库):select 1 把当前数据库切换到下标为 1 的数据库

        (2)move(移动当前db下的 anykey 到其他 db):move nowdb_anykey new_db  =》move a 1

        (3)flushdb  //清除当前数据库的所有 key

        (4)flushall  //清除所有数据库中的所有 key

    【3】事务 

    【3.1】概念

    所谓事务应具有以下特效:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation),持久性(Durability),简称ACID,但redis所提供的事务比较简单,它通过MULTI、EXEC、DISCARD和WATCH等命令实现事务。

    而Redis只支持简单的事务,将执行命令放入队列缓存,当程序中有异常或命令出错,执行DISCARD清空缓存队列不执行队列中命令,其事务过程有以下特点:

    • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

    • 事务是一个泛原子操作(这里我以泛原子称呼,在某些情况redis的事务不是原子性的,后续会说明):事务中的命令要么全部被执行,要么全部都不执行。

    EXEC 命令负责触发并执行事务中的所有命令:

    • 如果客户端在使用 MULTI 开启了一个事务之后,却因为断线而没有成功执行 EXEC ,那么事务中的所有命令都不会被执行。
    • 另一方面,如果客户端成功在开启事务之后执行 EXEC ,那么事务中的所有命令都会被执行。

    特别说明文中的泛原子操作

    • redis在开启事务以后,若执行命令具有显示的错误或者客户端中断则此次事务在执行EXEC命令时会调用DISCARD清空缓存队列不执行队列中的所有任务,此时是原子性的。
      •   (意思就是在multi 执行后,后面代码块输入出现语法错误,比如输入了一个不存在的命令等)
    • 当执行命令过程中,命令没有显示的报错(例如LSET操作设置一个不存在的list),而是在EXEC调用时候某个命令出错,那么在这之前已经执行的命令将不会回滚,所以严格说来,redis并不支持原子性。
      •   (意思是在exec后,事务某一行有报错(比如操作的key不存在,比如给字符串做算术运算等),那么忽略改行,其他的继续运行)

     与关系型数据库事务相比,

        (1)multi:可以理解成关系型事务中的 begin

        (2)exec :可以理解成关系型事务中的 commit

        (3)discard :可以理解成关系型事务中的 rollback

    【3.2】设计命令

    MULTI  #用于标记事务块的开始。Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令执行缓存队列中的命令。
    
    EXEC  #执行缓存队列中的命令
    
    DISCARD  #清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态,如果使用了WATCH命令,那么DISCARD命令就会将当前连接监控的所有键取消监控。
    
    WATCH key [key ...]   #当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的
    
    UNWATCH  #清除所有先前为一个事务监控的键,如果你调用了EXEC或DISCARD命令,那么就不需要手动调用UNWATCH命令

      (1)multi:开启事务,把执行的命令添加串行化的命令队列中,直到执行exec。这些命令就会被原子化的执行了。

        

       

    乐观锁机制

    乐观锁:总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或检查再设置(CAS)操作实现。

    redis通过WATCH命令实现乐观锁,作为WATCH命令的参数的键会受到Redis的监控,Redis能够检测到它们的变化。在执行EXEC命令之前,如果Redis检测到至少有一个键被修改了,那么整个事务便会中止运行,然后EXEC命令会返回一个nil值,提醒用户事务运行失败。

    注意:WATCH命令需要在MULTI之前执行,不然redis会将其一个命令放入缓存队列中。

    示例:在以下示例中通过一个客户端开启事务监听name键,另一个客户端在执行EXEC之前修改name键,此次事务将不会执行,并返回nil,如下。

      

      

    原子性实践

    为演示redis严格意义上将不支持原子性,做了一些简单实践。

      

    从上面的结果可以看出,在开启事务前name 值为Rose,在开启事务先后执行了SET命令和LSET命令,但是LSET命令是错误的,当我们调用EXEC执行事务完事务以后,在回头看事务中的SET命令已经生效,并未回滚,因为在次过程中该命令没有显示的报错,所以可以说redis的事务不支持原子性。

    参考:https://www.cnblogs.com/wdliu/p/9360286.html

  • 相关阅读:
    火焰图&perf命令
    C10K问题
    cocosStudio中使用PageView,ListView和ScrollView
    vim基本命令
    Git命令学习总结(-)
    可在 html5 游戏中使用的 js 工具库
    待飞日记(第十一篇)
    待飞日记(第十篇)
    待飞日记(第八天和第九天)
    高质量C++/C编程指南
  • 原文地址:https://www.cnblogs.com/gered/p/11679476.html
Copyright © 2020-2023  润新知