Redis 事务语句

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set te 1
QUEUED
127.0.0.1:6379> set te 2
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
127.0.0.1:6379> 

multi 申明一个事务的开始,然后后面的语句,返回QUEUED告诉我们语句进入了队列,但是并没有执行。 exec 告诉Redis服务器,进入队列的语句按照进入队列的顺序依次执行。

错误处理机制

如果事务中命令执行出错了,怎么处理呢?

命令错误主要有两种:

  1. 语法错误

     127.0.0.1:6379> multi
     OK
     127.0.0.1:6379> set te 3
     QUEUED
     127.0.0.1:6379> set te 4
     QUEUED
     127.0.0.1:6379> set te
     (error) ERR wrong number of arguments for 'set' command
     127.0.0.1:6379> exec
     (error) EXECABORT Transaction discarded because of previous errors.
     127.0.0.1:6379> get te
     "2"
    

事务中有命令语法错误,整个事务都不会继续执行,最后get命令获得的值依然是前一次设置的。

Redis 2.6.5 之前的版本会忽略包含错误语法的语句,执行正确的,也就是上面的命令,最终执行玩,get获得的值为4

  1. 运行错误

     127.0.0.1:6379> multi
     OK
     127.0.0.1:6379> set te 5
     QUEUED
     127.0.0.1:6379> sadd te 4
     QUEUED
     127.0.0.1:6379> set te 6
     QUEUED
     127.0.0.1:6379> set tee 7
     QUEUED
     127.0.0.1:6379> exec
     1) OK
     2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
     3) OK
     4) OK
     127.0.0.1:6379> get te
     "6"
     127.0.0.1:6379> get tee
     "7"
    

上面的命令中sadd te 4出现了错误,但是并不影响整个事务的执行,错误命令前后的正确命令都会继续执行。

特别注意:Redis不支持回滚功能,这点与关系型数据库不一样,如果执行出错,只能自己去把执行完的数据,给恢复原来的样子。

Watch 命令

Watch可以监控一个或多个键,一旦键值发生改变,事务就不会执行。监控会一直持续到exec命令,所以在multi命令后可以修改watch监控的键值。

127.0.0.1:6379> set name vilay
OK
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> set name jz
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name vilkay
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get name
"jz"

在multi之后,修改watch监控的值:

127.0.0.1:6379> set name vilay
OK
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> multi 
OK
127.0.0.1:6379> set name jz
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> get name
"jz"jz"