127.0.0.1:6379> multi #开启事务 OK 127.0.0.1:6379> set k1 v1 #命令入队 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> get k2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> get k1 QUEUED 127.0.0.1:6379> exec#执行 1) OK 2) OK 3) "v2" 4) OK 5) "v1"
命令
multi:开启事务
exec:执行事务
discard:取消事务
1 2 3 4 5 6 7 8
127.0.0.1:6379> multi #开启事务 OK 127.0.0.1:6379> set k5 qweasd QUEUED 127.0.0.1:6379> discard #取消事务 OK 127.0.0.1:6379> get k5 # 事务队列命令不会被执行 (nil)
特性
若事务中出现错误命令,exec后事务中所有命令都不会被执行;
若事务队列中出现“运行时异常”,在事务执行过程中,其他命令可以被正常执行。
错误命令抛出异常
编译时异常
一个命令出现错误,事务中所有命令都不会被执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
127.0.0.1:6379> multi OK 127.0.0.1:6379> 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> getset k3 #错误的命令 (error) ERR wrong number of arguments for'getset'command#报错后事务没有停止 127.0.0.1:6379> set k4 v4 QUEUED 127.0.0.1:6379> set k5 v4 QUEUED 127.0.0.1:6379> exec (error) EXECABORT Transaction discarded because of previous errors. #所有的命令都不会被执行
运行时异常
所有的命令中,除了报错的,都正常执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> incr k1 #k1是一个字符串,不能进行incr,所以是一个会报错的命令 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> get k3 QUEUED 127.0.0.1:6379> exec 1) (error) ERR value is not an integer or out of range 2) OK 3) OK 4) "v3" 127.0.0.1:6379> get k3 "v3"
127.0.0.1:6379> set money 100 OK 127.0.0.1:6379> set out 0 OK 127.0.0.1:6379> watch money OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> decrby money 20 QUEUED 127.0.0.1:6379> incrby out 20 QUEUED 127.0.0.1:6379> exec 1) (integer) 80 2) (integer) 20
执行失败示例
1 2 3 4 5 6 7 8 9 10 11 12
127.0.0.1:6379> set money 10 OK 127.0.0.1:6379> watch money OK 127.0.0.1:6379> multi OK #在这里,另一个线程执行了set money 100 127.0.0.1:6379> incrby money 20 QUEUED 127.0.0.1:6379> exec (nil) #由于money值被另一个线程修改,这里执行失败 127.0.0.1:6379> get money "100"