MULTI 、EXEC 、DISCARD 和WATCH 是 Redis 事务的基础
multi开启一个事务,成功返回OK。
例如:程序员
127.0.0.1:6379> multi OK 127.0.0.1:6379> set name allen QUEUED 127.0.0.1:6379> set age 30 QUEUED 127.0.0.1:6379> exec 1) OK 2) OK
如例所示,开启一个事务以后,设置一个键值,返回QUEUED,表明已经放入一个队列。
exec 按照队列依次执行。
discard 命令其实就是清空事务命令并退出事务上下文,也就是咱们常说的事务回滚。.net
127.0.0.1:6379> multi OK 127.0.0.1:6379> set name frank QUEUED 127.0.0.1:6379> set age 16 QUEUED 127.0.0.1:6379> discard OK 127.0.0.1:6379> get name "allen" 127.0.0.1:6379> get age "28"
如例所示,开启一个事务以后,设置了两个键值,可是不但愿事务执行,使用命令discard,令事务回滚,输出name键和age键,仍是原来的值,说明事务已经回滚。版本控制
若是队列中的某一个命令执行错误,整个事务不会回滚!
举例说明:incr命令可使键的值自增1,可是只能针对int类型的值,字符串的值就会报错。code
127.0.0.1:6379> multi OK 127.0.0.1:6379> incr name QUEUED 127.0.0.1:6379> incr age QUEUED 127.0.0.1:6379> exec 1) (error) ERR value is not an integer or out of range 2) (integer) 29 127.0.0.1:6379> get age "29"
由于name的值是allen,incr执行果真报了错。可是age的值却执行成功。整个事务并无咱们预想中的回滚!blog
watch命令会监视给定的key,当exec的时候若是监视的key从调用watch以后发生过变化,则整个事务会失败。也能够调用watch屡次监视多个key。这样就能够对指定的key加乐观锁了。注意watch的key是对整个链接有效的,事务也同样。若是链接断开,监视和事务都会被自动清除。固然,exec、discard、unwatch命令都会清除链接中的全部监视。其实,乐观锁的概念就好像咱们使用的版本控制器的概念。
打开终端1:队列
127.0.0.1:6379> watch name OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> set name allen QUEUED
在终端1中,使用watch监视name键,而后开启事务,设置name键的值为allen。
开启另一个终端,命名终端2:事务
127.0.0.1:6379> set name frank OK
在终端2中,将name键的值设置为frank。
这时候执行终端1中的事务:字符串
127.0.0.1:6379> watch name OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> set name allen QUEUED 127.0.0.1:6379> exec (nil) 127.0.0.1:6379> get name "frank"
这时候能够看到,终端1中的事务并无执行成功,当获取name键的时候,返回的是在终端2中设置的值。
这就好像版本控制器同样,版本号为1的文件,被A,B两个程序员下载,A程序员作完修改后,版本号变成了2,而后提交,版本库进行了一个判断,提交上来的版本号大于版本库的版本号,说明提交上来的内容是新内容,OK,完成提交。这时候,B程序员也完成了修改,版本号变成了2,他也尝试着提交,版本库一样作出了一个判断,版本库和提交上来的版本都是2,版本库认为B程序员提交上来的内容已通过期,不容许提交。能够这样简单的理解。get
学PHP的小蚂蚁 原创博客 http://my.oschina.net/woshixiaomayi/blog博客