Redis事务和数据库的事务严格意义来说是不一样的,Redis的事务是通过一组命令的集合,Redis事务提供了一种将多个命令请求打包,然后一次性的、按顺序的执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去执行其他客户端的命令请求。

Redis 通过 MULTI(标记一个事务块的开始)EXEC(执行)DISCARD(放弃执行事务块内的所有命令)WATCH(乐观锁) 四个命令来实现事务功能。一个事务从开始到结束通常会经历以下三个阶段:

  • 事务开始
  • 命令入队
  • 事务执行

以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:

redis> MULTI
OK

redis> SET book-name "Mastering C++ in 21 days"
QUEUED

redis> GET book-name
QUEUED

redis> SADD tag "C++" "Programming" "Mastering Series"
QUEUED

redis> SMEMBERS tag
QUEUED

redis> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
   2) "C++"
   3) "Programming"
WATCH和UNWATCH

WATCH命令是一个乐观锁,它可以在EXEC命令执行之前,见识任意数量的key,并在EXEC执行时,检查被监视的key是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行,并向客户端返回代表事务执行失败的空回复。

redis> WATCH key
OK

redis> MULTI
OK

redis> SET key value
QUEUED

redis> EXEC
(nil)
redis> WATCH key
OK

redis> UNWATCH
OK

注意:WATCHUNWATCH一定要结合使用。被监控的key如果不主动释放(UNWATCH),或者没有执行EXEC指令时,被WATCH的键还会一直被监控,影响后续的效率。

DISCARD

DISCARD 命令用于取消一个事务, 它清空客户端的整个事务队列, 然后将客户端从事务状态调整回非事务状态, 最后返回字符串 OK 给客户端, 说明事务已被取消。

redis> MULTI
OK

redis> PING
QUEUED

redis> SET greeting "hello"
QUEUED

redis> DISCARD
OK
Redis事务不支持回滚

redis的原子性可以这样子理解:事务队列中的命令要么全部执行,要么全部不执行,因此redis事务是不具有原子性的。

但是redis是不支持回归机制的,就是说事务队列中的某个命令失败了,整个事务也会继续执行下去,直到所有的命令都执行完毕。