Fork me on GitHub

redis事务

一、官网解释

事务可以一次执行多个命令,并且带有以下两个重要保证:
①事务是一个单独的隔离操作:事务中的所有命令都会序列化,按顺序的执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
②事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

二、用法

multi命令用于开启一个事务,它总是返回OK。
multi执行之后,客户端可以继续向服务器发送任意命令,这些命令不会被立即执行,而是被放到一个队列中,当exec命令被调用时,所以得命令才会被执行。
另一方面,通过discard,客户端可以清空事务队列,并放弃执行事务。

a.正常执行

>set k1 v1
>set k2 v2
>set k3 1

> mutli
OK
>set k1 v11
QUEUED

>incr k3
QUEUED

>exec

b.放弃事务

>set foo 1
OK

>multi
OK

>incr foo
queued

>discard
OK

>get foo
"1"

c.全体连坐

> set foo 1

> multi
OK

> incr foo

> incr foo

>sett foo 2
(error) ERR unknow commad 'setg'

>exec
(error) EXECABORT transaction discarded because of previous errors

>get foo
"1"

d.源头债主

> set foo 1
> set foo2 v1

> multi

> incr foo
QUEUED

> incr foo2
QUEUED

>exec
1) (integer) 2
2) (error) ERR value is not a integer or out of range

三、watch监控

a.官方解释

watch使得exec命令需要有条件地执行:事务只能在所有被监视的键没被修改的前提之下执行,如果这个前提不能满足的话,事务就不会被执行。
但是 :如果你使用watch监视了一个带过期时间的键,那么即使这个键过期了,事务仍然可以正常执行,关于这个方面的详细情况,请看这个http://code.google.com/p/redis/issues/detail?id=270

b.用法

watch命令可以被调用多次。对键的监视从watch执行之后开始开始生效,知道调用exec为止。
用户还可以在单个watch命令中监视任意多个键,例如:
> watch key1 key2 key3
当exec被调用时,不管事务是否成功执行,对所有键的监视都会被取消。

另外,客户端断开连接时,该客户端对键的监视也会被取消。

使用无参数unwatch命令可以手动取消对所有键的监视。对于一些需要改动多个键的事务,有时候程序需要同时对多个键惊醒加锁,然后检查这些键的当前值是否符合程序的要求。但值达不到要求时,就可以使用unwatch命令来取消目前对键的监视,中途放弃这个事务,并等待事务的下次尝试。
线程1:
> watch foo
OK
> multi
OK

线程2:
> incr foo
(integer) 2

线程1继续:
> incr foo
QUEUED
>exec
(nil)
>get foo
"2"

四、redis事务的特性

①单独的隔离操作:事务中的所有命令都会序列化,按顺序执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
②没有隔离操作:队列中的命令没有提交之前不会实际的被执行,因为事务提交之前任何指令都不会被实际执行,也就不存在 “ 事务的查询要看到事务里的更新,在事务外查询不到 ”这个让人十分头痛的问题。
③:不保证原子性:redis同一个事务如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。

 

关注我的公众号,精彩内容不能错过

 

posted @ 2017-07-24 11:58  程序员果果  阅读(147)  评论(0编辑  收藏  举报