`
wx1569567608
  • 浏览: 71187 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Redis学习手册(事务)

 
阅读更多

一、概述:

      和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制。在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基石。相信对有关系型数据库开发经验的开发者而言这一概念并不陌生,即便如此,我们还是会简要的列出Redis中事务的实现特征:
      1). 在事务中的所有命令都将会被串行化的顺序执行,事务执行期间,Redis不会再为其它客户端的请求提供任何服务,从而保证了事物中的所有命令被原子的执行。
      2). 和关系型数据库中的事务相比,在Redis事务中如果有某一条命令执行失败,其后的命令仍然会被继续执行。
      3). 我们可以通过MULTI命令开启一个事务,有关系型数据库开发经验的人可以将其理解为"BEGIN TRANSACTION"语句。在该语句之后执行的命令都将被视为事务之内的操作,最后我们可以通过执行EXEC/DISCARD命令来提交/回滚该事务内的所有操作。这两个Redis命令可被视为等同于关系型数据库中的COMMIT/ROLLBACK语句。
      4). 在事务开启之前,如果客户端与服务器之间出现通讯故障并导致网络断开,其后所有待执行的语句都将不会被服务器执行。然而如果网络中断事件是发生在客户端执行EXEC命令之后,那么该事务中的所有命令都会被服务器执行。
      5). 当使用Append-Only模式时,Redis会通过调用系统函数write将该事务内的所有写操作在本次调用中全部写入磁盘。然而如果在写入的过程中出现系统崩溃,如电源故障导致的宕机,那么此时也许只有部分数据被写入到磁盘,而另外一部分数据却已经丢失。Redis服务器会在重新启动时执行一系列必要的一致性检测,一旦发现类似问题,就会立即退出并给出相应的错误提示。此时,我们就要充分利用Redis工具包中提供的redis-check-aof工具,该工具可以帮助我们定位到数据不一致的错误,并将已经写入的部分数据进行回滚。修复之后我们就可以再次重新启动Redis服务器了。

二、相关命令列表:

命令原型 时间复杂度 命令描述 返回值
MULTI   用于标记事务的开始,其后执行的命令都将被存入命令队列,直到执行EXEC时,这些命令才会被原子的执行。 始终返回OK
EXEC   执行在一个事务内命令队列中的所有命令,同时将当前连接的状态恢复为正常状态,即非事务状态。如果在事务中执行了WATCH命令,那么只有当WATCH所监控的Keys没有被修改的前提下,EXEC命令才能执行事务队列中的所有命令,否则EXEC将放弃当前事务中的所有命令。 原子性的返回事务中各条命令的返回结果。如果在事务中使用了WATCH,一旦事务被放弃,EXEC将返回NULL-multi-bulk回复。
DISCARD   回滚事务队列中的所有命令,同时再将当前连接的状态恢复为正常状态,即非事务状态。如果WATCH命令被使用,该命令将UNWATCH所有的Keys。 始终返回OK。
WATCHkey [key ...] O(1) 在MULTI命令执行之前,可以指定待监控的Keys,然而在执行EXEC之前,如果被监控的Keys发生修改,EXEC将放弃执行该事务队列中的所有命令。 始终返回OK。
UNWATCH O(1) 取消当前事务中指定监控的Keys,如果执行了EXEC或DISCARD命令,则无需再手工执行该命令了,因为在此之后,事务中所有被监控的Keys都将自动取消。 始终返回OK。

三、命令示例:

   1. 事务被正常执行:
    #在Shell命令行下执行Redis的客户端工具。
    /> redis-cli
    #在当前连接上启动一个新的事务。

    redis 127.0.0.1:6379> multi
    OK
    #执行事务中的第一条命令,从该命令的返回结果可以看出,该命令并没有立即执行,而是存于事务的命令队列。
    redis 127.0.0.1:6379> incr t1
    QUEUED
    #又执行一个新的命令,从结果可以看出,该命令也被存于事务的命令队列。
    redis 127.0.0.1:6379> incr t2
    QUEUED
    #执行事务命令队列中的所有命令,从结果可以看出,队列中命令的结果得到返回。
    redis 127.0.0.1:6379> exec
    1) (integer) 1
    2) (integer) 1
        
   2. 事务中存在失败的命令:
    #开启一个新的事务。
    redis 127.0.0.1:6379> multi
    OK
    #设置键a的值为string类型的3。
    redis 127.0.0.1:6379> set a 3
    QUEUED
    #从键a所关联的值的头部弹出元素,由于该值是字符串类型,而lpop命令仅能用于List类型,因此在执行exec命令时,该命令将会失败。
    redis 127.0.0.1:6379> lpop a
    QUEUED
    #再次设置键a的值为字符串4。
    redis 127.0.0.1:6379> set a 4
    QUEUED
    #获取键a的值,以便确认该值是否被事务中的第二个set命令设置成功。
    redis 127.0.0.1:6379> get a
    QUEUED
    #从结果中可以看出,事务中的第二条命令lpop执行失败,而其后的set和get命令均执行成功,这一点是Redis的事务与关系型数据库中的事务之间最为重要的差别。
    redis 127.0.0.1:6379> exec
    1) OK
    2) (error) ERR Operation against a key holding the wrong kind of value
    3) OK
    4) "4"

   3. 回滚事务:
    #为键t2设置一个事务执行前的值。
    redis 127.0.0.1:6379> set t2 tt
    OK
    #开启一个事务。
    redis 127.0.0.1:6379> multi
    OK
    #在事务内为该键设置一个新值。
    redis 127.0.0.1:6379> set t2 ttnew
    QUEUED
    #放弃事务。
    redis 127.0.0.1:6379> discard
    OK
    #查看键t2的值,从结果中可以看出该键的值仍为事务开始之前的值。
    redis 127.0.0.1:6379> get t2
    "tt"

四、WATCH命令和基于CAS的乐观锁:

      在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能。假设我们通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Null multi-bulk应答以通知调用者事务执行失败。例如,我们再次假设Redis中并未提供incr命令来完成键值的原子性递增,如果要实现该功能,我们只能自行编写相应的代码。其伪码如下:
      val = GET mykey
      val = val + 1
      SET mykey $val
      以上代码只有在单连接的情况下才可以保证执行结果是正确的,因为如果在同一时刻有多个客户端在同时执行该段代码,那么就会出现多线程程序中经常出现的一种错误场景--竞态争用(race condition)。比如,客户端A和B都在同一时刻读取了mykey的原有值,假设该值为10,此后两个客户端又均将该值加一后set回Redis服务器,这样就会导致mykey的结果为11,而不是我们认为的12。为了解决类似的问题,我们需要借助WATCH命令的帮助,见如下代码:
      WATCH mykey
      val = GET mykey
      val = val + 1
      MULTI
      SET mykey $val
      EXEC
      和此前代码不同的是,新代码在获取mykey的值之前先通过WATCH命令监控了该键,此后又将set命令包围在事务中,这样就可以有效的保证每个连接在执行EXEC之前,如果当前连接获取的mykey的值被其它连接的客户端修改,那么当前连接的EXEC命令将执行失败。这样调用者在判断返回值后就可以获悉val是否被重新设置成功。

转载于:https://my.oschina.net/u/1780368/blog/718735

分享到:
评论

相关推荐

    Redis学习资料

    Redis学习手册 事务 doc Redis学习资料 rar redis讲义 doc">redis 2 8 13 tar gz redisbin x32 zip redisbin x64 zip Redis学习手册 Hash数据类型 doc Redis学习手册 Key操作命令 doc Redis学习手册 List数据类型 ...

    Redis学习指南 Redis学习手册

    Redis,全称Remote Dictionary Server,是一款高性能的键值存储系统,常被用于...通过阅读"Redis学习手册",你将能够深入了解Redis的工作原理,熟练使用其各种功能,从而在你的IT职业生涯中发挥出Redis的强大效能。

    Redis学习手册带详细教程

    Redis学习手册带详细教程 一、Redis概述 Redis是当前最流行的NoSQL数据库之一,它是一个开源的、基于内存的数据存储系统,可以用作数据库、消息队列、缓存等。Redis的主要特点是高性能、低延迟、支持事务、支持...

    Redis参考手册-中文-离线chm版本

    总的来说,Redis中文版离线手册是学习和使用Redis的重要参考资料。CHM文件格式便于离线查阅,涵盖了Redis的安装、配置、使用、高级特性和最佳实践等内容,对于开发者来说是一份宝贵的工具书。通过深入阅读和实践,...

    Redis 命令参考手册中文完整版chm

    本压缩包包含的"Redis参考手册.CHM"是Redis命令的中文完整版手册,对于学习和使用Redis的开发者来说,是一份极其实用的资料。 一、Redis数据类型 Redis支持五种基本数据类型:字符串(String)、哈希(Hash)、...

    php-redis中文手册

    提供的`php-redis中文帮助手册.chm`文件是关于PHP Redis扩展的中文文档,包含了所有函数的详细说明、参数和返回值,是学习和解决问题的重要参考资料。开发者可以通过查阅手册,更深入地了解和掌握PHP Redis的各种...

    redis入门手册(中文)

    4. **事务(Transactions)**:学习如何在Redis中使用`MULTI`、`EXEC`命令进行事务操作,保证多条命令的原子性执行。 5. **发布/订阅(Publish/Subscribe)**:理解Redis的消息订阅和发布模型,如何创建频道、发送...

    redis帮助手册.zip

    2019年的这个“redis帮助手册”是为Redis学习者和开发者提供的一份详尽参考资料,包含了Redis的命令使用方法和代码示例。 Redis作为一款NoSQL数据库,其主要特点是数据结构丰富,支持字符串、哈希、列表、集合、...

    Redis学习手册中文PDF版最新版本

    Redis是一款开源的高性能键值存储数据库,其作为...通过阅读这份最新的《Redis学习手册中文PDF版》,开发者可以快速掌握Redis的核心概念、操作命令以及高级特性,从而在实际工作中更加得心应手地使用这一强大的工具。

    Redis命令参考手册完整版.pdf

    "Redis命令参考手册完整版.pdf"是学习和使用Redis的重要资源,包含了Redis所有命令的详细说明。 1. **基础命令**: - `SET`:设置键的值,例如`SET key value`,创建或更新键值对。 - `GET`:获取键的值,例如`...

    redis学习pdf手册

    本PDF手册详细介绍了Redis的使用方法及其在各种应用中的实践。 一、Redis基本概念 Redis(Remote Dictionary Server)是意大利开发者Antonio Filieri开发的一款内存数据结构存储系统。它支持多种数据结构,如字符串...

    Redis实战手册

    总的来说,《Redis实战手册》是一本全面且深入的Redis学习资料,无论是初学者还是经验丰富的开发者,都能从中受益。通过阅读本书,你可以了解到Redis的全貌,掌握其核心功能,以及如何在实际开发中充分发挥Redis的...

    phpredis中文手册.pdf

    Redis 支持事务,`MULTI` 开始一个事务,`EXEC` 提交事务,`DISCARD` 取消事务。例如: ```php $redis->multi(); $redis->set('key1', 'value1'); $redis->set('key2', 'value2'); $result = $redis->exec(); ``` #...

    Redis学习手册.docx

    1. 易用性:Redis 的命令接口简洁明了,对于熟悉其他键值存储系统的开发者来说,学习曲线较低,能够快速上手。 2. 解决方案多样性:Redis 提供了多种内置功能,如索引、排序、发布/订阅(Publication/Subscription)...

    Redis学习手册

    伸缩性,支持事务及嵌套事务,海量数据存储等重要特征,在用于存储实时数据方面具有极高的可用价值。 然而需要指出的是,该产品的 Licence 为 GPL,这就意味着它并不是在所有情况下都是免费使用的。 2). 对 MongoDB ...

    redis使用中文参考手册

    Redis是一款高性能的键值存储系统,常用于数据库、缓存和消息中间件。这份“redis使用中文参考手册”是开发者们了解和操作Redis的...通过深入学习和实践,你将能够熟练掌握Redis的各种操作,并将其潜力充分发挥出来。

    redis详细使用手册

    Redis是一款高性能的...通过"redis使用手册.doc"、"redis.pdf"和"redis_.pptx",你可以深入学习上述知识点,逐步成为Redis的专家。同时,"redis自启动服务设置.txt"将帮助你在实际环境中更好地管理和维护Redis服务。

    redis中文参考手册.pdf

    首先,Redis中文参考手册是学习Redis的基础,它详细介绍了Redis的所有命令、数据类型和配置选项。在手册中,你会了解到Redis支持的基本数据结构,如字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)和有序...

    redis4.0中文手册

    redis4.0中文手册,打包成chm文档。方便查看。本文档是 Redis Command Reference 和 Redis Documentation 的中文翻译版, 阅读这个文档可以帮助你了解 Redis 命令的具体使用方法, 并学会如何使用 Redis 的事务、...

Global site tag (gtag.js) - Google Analytics