首页 > 代码库 > Redis学习笔记06Redis命令之(5)事务
Redis学习笔记06Redis命令之(5)事务
1.1.1. multi
开始一个新事务。
redis.coe2coe.me:6379> multi
OK
执行此命令后,后面执行的set等命令将被缓存,直到被discard命令取消,或者被exec命令提交执行。
一旦执行了multi,再执行的命令,将被缓存到一个执行队列中,而不是立即执行。因此这些命令的执行的结果,再其它客户端连接中是看不到的。
比如:
在连接1中:
redis.coe2coe.me:6379> select 0
OK
redis.coe2coe.me:6379> keys *
1) "port"
2) "host"
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> set a 1
QUEUED
返回值QUEUED表示当前命令并未执行,只是缓存到了执行队列中。因此键a在其它连接中不可见。
redis.coe2coe.me:6379> get a
QUEUED
redis.coe2coe.me:6379> get host
QUEUED
在连接2中:
redis.coe2coe.me:6379> select 0
OK
redis.coe2coe.me:6379> keys *
1) "port"
2) "host"
redis.coe2coe.me:6379> get a
(nil)
在连接1执行exec提交执行之前,键a是不可见的。
redis.coe2coe.me:6379> get host
"redis.coe2coe.me"
查询事务开始之前已经存在的键,是可以成功的。
1.1.2. discard
discard命令取消从最近的multi命令到discard之间的所有命令,这些命令将不会被执行,数据也不会被修改。
redis.coe2coe.me:6379> keys *
1) "port"
2) "host"
redis.coe2coe.me:6379> get host
"redis.coe2coe.me"
redis.coe2coe.me:6379> get port
"6379"
redis.coe2coe.me:6379> multi
OK
开启事务成功。
redis.coe2coe.me:6379> set a 1
QUEUED
这个命令暂时未执行,而是被加到队列中。
redis.coe2coe.me:6379> set b 1
QUEUED
redis.coe2coe.me:6379> set c 1
QUEUED
redis.coe2coe.me:6379> discard
OK
取消所有命令,清空执行队列。
redis.coe2coe.me:6379> keys *
1) "port"
2) "host"
再次检查键的集合,发现键a,b,c并没有增加到数据库中。
如果没有执行MULTI就执行DISCARD,则报错。
redis.coe2coe.me:6379> discard
(error) ERR DISCARD without MULTI
1.1.3. exec
将multi到exec之间的所有命令提交执行。
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> set host redis101.coe2coe.me
QUEUED
redis.coe2coe.me:6379> set a 1
QUEUED
redis.coe2coe.me:6379> set b 1
QUEUED
redis.coe2coe.me:6379> exec
1) OK
2) OK
3) OK
redis.coe2coe.me:6379> keys *
1) "port"
2) "b"
3) "a"
4) "host"
发现增加了a,b两个键。
redis.coe2coe.me:6379> get host
"redis101.coe2coe.me"
发现host这个键的值被修改了。
Redis事务的特点:
(1)原子性。
在执行exec命令时,multi和exec之间的命令将被顺序执行,而且是当做一个命令整体执行的,在这些命令执行过程中,Redis确保不会穿插执行其它客户端连接发送的命令。
这些命令要么全部被执行,要么一个也不执行。
(2)出错则取消
如果有一个命令格式不正确,则稍后执行exec时将取消所有命令,即使其中包含一些正确的可执行命令。
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> set a,3,4
(error) ERR wrong number of arguments for ‘set‘ command
redis.coe2coe.me:6379> set b 4
QUEUED
redis.coe2coe.me:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
1.1.4. watch
观察一个键的值,检测是否被其它客户端连接修改了。
连接1:
redis.coe2coe.me:6379> set a 1
OK
redis.coe2coe.me:6379> get a
"1"
redis.coe2coe.me:6379> watch a
OK
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> set b 1
QUEUED
此时,在连接2中执行如下命令:
redis.coe2coe.me:6379> set a 2
OK
此时,再到连接1中执行如下命令:
redis.coe2coe.me:6379> exec
(nil)
返回值nil表明事务执行出错了,即所有语句都没执行。
redis.coe2coe.me:6379> get a
"2"
redis.coe2coe.me:6379> get b
(nil)
在multi和exec或discard之间执行watch会导致出错。
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> watch a
(error) ERR WATCH inside MULTI is not allowed
1.1.5. unwatch
取消对所有被观察的键的观察。
执行exec和discard将自动执行unwatch,即自动取消对所有被观察的键的观察。
当执行了watch的连接断开之后,自动unwatch。
redis.coe2coe.me:6379> unwatch
OK
Redis学习笔记06Redis命令之(5)事务