小蚂蚁学习Redis笔记(10)——Redis重要特性——事务处理

1.Redis重要特性之事务处理

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键,仍是原来的值,说明事务已经回滚。版本控制

Redis的事务处理有个特别须要注意的地方!

若是队列中的某一个命令执行错误,整个事务不会回滚!
举例说明: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

2.乐观锁的复琐事务控制

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博客

相关文章
相关标签/搜索