redis使用手册,redis事务相关的命令
Redis学习手册(事务)-斯蒂芬_刘-博客花园
Redis学习手册(事务)贴于2012-03-28 09: 28 Stephen _ Liu阅读(833)评论(0)编辑收藏一、概述:
和许多其他数据库一样,Redis作为一个NoSQL数据库,也提供了事务机制。在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们事务的基石。相信这个概念对于有关系数据库开发经验的开发者来说并不陌生。尽管如此,我们还是要简单列出Redis中事务的实现特性:
1)事务中的所有命令将按串行顺序执行。在事务执行过程中,Redis不会为其他客户端的请求提供任何服务,从而保证事务中的所有命令都由atoms执行。
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执行后才会被atoms执行。总是返回OKEXEC来执行一个事务内命令队列中的所有命令,同时将当前连接的状态恢复到正常状态,即非事务状态。如果在事务中执行WATCH命令,则只有在WATCH所监视的键没有被修改的情况下,exec命令才能执行事务队列中的所有命令,否则EXEC将放弃当前事务中的所有命令。Atomic返回事务中每个命令的结果。如果在事务中使用WATCH,一旦事务被放弃,EXEC将返回一个NULL-multi-bulk回复。DISCARD回滚事务队列中的所有命令,同时将当前连接的状态恢复到正常状态,即非事务状态。如果使用WATCH命令,它将解除对所有键的监视。总是返回OK。手表钥匙.]O(1)在执行MULTI命令之前,您可以指定要监控的按键。但是,在执行exec之前,如果被监控的键被修改,EXEC将放弃执行该事务队列中的所有命令。总是返回OK。UNWATCHO(1)取消当前事务中指定的监控键。如果执行EXEC或DISCARD命令,则不需要手动执行该命令,因为在此之后,事务中所有被监控的键都将被自动取消。总是返回OK。三。命令示例:
1.交易正常执行:
#在Shell命令行执行Redis的客户端工具。
/redis-cli
#在当前连接上启动新事务。
redis 127.0.0.1:6379多
好
#执行事务中的第一个命令。从这个命令的返回结果可以看出,这个命令不是立即执行,而是存储在事务的命令队列中。
redis 127.0.0.1:6379增量t1
排队
#再次执行新命令。从结果中可以看出,这个命令也存储在事务的命令队列中。
redis 127.0.0.1:6379增量t2
排队
#执行事务命令队列中的所有命令。从结果中可以看出,返回了队列中命令的结果。
redis 127.0.0.1:6379 exec
1)(整数)1
2)(整数)1
2.事务中有失败的命令:
#开始新的交易。
redis 127.0.0.1:6379多
好
#将关键字A的值设置为string类型的3。
redis 127.0.0.1:6379设置一个3
排队
#从与键a相关联的值的头部弹出元素。因为该值是字符串类型,并且lpop命令只能用于列表类型,所以exec命令在执行时将会失败。
127.0.0.1:6379
排队
#再次将键A的值设置为字符串4。
redis 127.0.0.1:6379设置一个4
排队
#获取key A的值,以确认它是否被事务中的第二个set命令成功设置。
redis 127.0.0.1:6379获得a
排队
#从结果可以看出,事务中的第二个命令lpop失败,而后续的set和get命令执行成功。这是Redis事务与关系数据库事务最重要的区别。
redis 127.0.0.1:6379 exec
1)好的
2) (error)针对持有错误类型值的键的ERR操作
3)好
4) 4
3.回滚事务:
#为键t2设置交易前值。
redis 127.0.0.1:6379设置t2 tt
好
#打开交易。
redis 127.0.0.1:6379多
好
#在事务中为该键设置一个新值。
redis 127.0.0.1:6379设置T2 TT新
排队
#放弃交易。
redis 127.0.0.1:6379丢弃
好
#检查key t2的值,从结果可以看出,这个key的值仍然是事务开始前的值。
redis 127.0.0.1:6379获取t2
tt的
四。WATCH命令和基于CAS的乐观锁定:
在Redis的事务中,WATCH命令可以用来提供CAS(check-and-set)功能。假设我们在WATCH命令执行事务之前监视多个键。如果任何键的值在监视后发生变化,则exec命令执行的事务将被放弃,并且将返回一个空的多批量响应,通知调用者事务执行失败。例如,让我们再次假设Redis中没有提供incr命令来完成键值的原子增量。如果要实现这个功能,只能自己编写相应的代码。伪代码如下:
val=获取我的密钥
瓦尔=瓦尔1
设置我的密钥$val
上面的代码只能保证在单连接的情况下执行结果是正确的,因为如果多个客户端同时在执行这段代码,就会出现错误场景——竞态条件,这种情况经常出现在多线程程序中。比如A客户端和B客户端同时读取mykey的原始值,假设该值为10,然后两个客户端都会在该值上加1,并设置回Redis服务器,这样就会导致mykey的结果为11,而不是我们认为的12。要解决类似的问题,我们需要WATCH命令的帮助,如下面的代码所示:
注意我的钥匙
val=获取我的密钥
瓦尔=瓦尔1
多(前缀)
设置我的密钥$val
高级管理人员
与之前的代码不同的是,新代码在获取mykey的值之前,先通过WATCH命令对其进行监控,然后在事务中封装set命令,可以有效保证每个连接之前执行EXEC命令。如果当前连接获得的mykey值被其他连接的客户端修改,则当前连接的exec命令将无法执行。这样调用者判断返回值后就可以知道val是否已经复位成功。