对于redis中的事务,需要用multi和exec来提交一个事务:
root@wsdc-server:~/Downloads/redis-3.0.0-rc1/src# ./redis-cli -p 6379
127.0.0.1:6379> multi // 标示事务的开始
OK
127.0.0.1:6379> set "name" "practical common lisp" // 事务命令入队
QUEUED
127.0.0.1:6379> get "name"
QUEUED
127.0.0.1:6379> set "author" "Peter Seibel"
QUEUED
127.0.0.1:6379> get "author"
QUEUED
127.0.0.1:6379> exec // 当事务入队之后,遇到了 exec, discard, watch, multi 四个命令中的任何一个,就会立即执行该命令
1) OK
2) "practical common lisp"
3) OK
4) "Peter Seibel"
对于watch命令,它是一个乐观锁(optimistic locking),它可以再exec执行之前,监视任意数量的数据库键,并在exec命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行事务,并向客户端返回事务执行失败的空回复。下面举例:
时间 | 客户端A | 客户端B |
T1 | WATCH "name" | |
T2 | MULTI | |
T3 | SET "name" "peter" | |
T4 | SET "name" "john" | |
T5 | EXEC |
在该例子中,客户端A一开始就监视了name这一个键。发现在A在执行事务的过程中,B去修改了该值,所以会引发事务失败。
watch的触发:
所有对数据库进行修改的命令,比如 set, lpush, sadd, zrem, del, flushdb 等都可以触发watch。这些命令在执行之后,都会调用multi.c/touchWatchKey函数,对watched_keys字典进行检查,查看是否有客户端正在监视刚刚被命令修改过的数据库键,如果有的话,那么touchWatchKey函数就会将监视被修改的客户端的REDIS_DIRTY_CAS标识打开,标识该客户端的事务安全性已经被破坏。