Medusar's Blog
敬畏知识,谦逊前行
Toggle navigation
Medusar's Blog
主页
Booklist
Resources
About Me
归档
标签
Redis事务
Redis
NoSQL
2016-06-19 00:58:32
479
0
0
medusar
Redis
NoSQL
## Redis事务的实现 1. redis的事务通过MULTI,EXEC,WATCH,DISCARD等命令实现。 2. Redis通过MULTI命令开启事务,通过EXEC提交事务,通过DISCAR放弃事务 3. Redis事务执行的结果会按顺序返回给客户端。 Redis事务一般包含三个阶段 1)开始事务 2)命令入队 3)事务执行 ### 开始事务 通过MULTI命令开始事务,MULTI命令把执行该命令的客户端从非事务态转为事务态。该命令服务端始终返回OK ### 命令入队 开启事务之后,客户端向服务端发送的命令不会被立即执行,服务端会将这些命令放入一个事务队列,同时响应给客户端QUEUED。 ### 命令执行 客户端向服务端发送EXEC命令之后,服务端事务队列中的事务会被按顺序执行 ,最后执行命令所得结果全部返回客户端 。 ## Redis事务的特性 数据库事务的ACID特性在Redis中是否都满足呢? ### 原子性 Redis事务满足原子性。事务队列中的命令要么全部执行,要么全部放弃。 需要注意的是,如果在事务队列中的命令执行的时候,某些命令执行出错,那么也不会影响其他命令的执行。比如命令A,B,C,D是在一个事务中,假如B执行出错了,那么ACD三个命令依然会执行,并且执行结果也会生效。这一点与MySQL等关系型数据库不同,原因在于Redis事务不支持回滚,而不支持回滚的原因是Redis的开发者认为这会使redis复杂。 ### 隔离型 Redis是单线程的,并且服务端保证在执行事务期间不会对事务进行中断,所以Redis的事务总是以串行方式运行的,所以,Redis的事务也是具有隔离性的。 ### 一致性 数据库的一致性指的是数据库中数据的状态变化总是从一个一致性的状态变化到另外一个一致性的状态。即事务执行前是一致的,事务执行之后,状态也应该是一致的。 Redis事务也具备一致性,从以下三个方面进行保证: #### 入队错误 事务开启后,如果一个命令入队时出错(比如命令的参数个数不对或者命令不存在),那么收到客户端的EXEC命令之后,Redis将拒绝执行事务。 PS:入队错误,不会返回给客户端QUEUED,所以客户端可以知道命令出错,最后通过DISCARD放弃 事务,当然如果客户端仍然发送了EXEC,那么服务端也不会执行。 #### 执行错误 与入队错误不同,执行错误指的是命令执行的时候发生的错误(比如对STRING类型的Key进行LPUSH操作)。 如果发生执行错误,服务器不会中断事务的执行,它会继续执行余下的其他命令,并且已经执行的命令不会受出错命令的影响。 #### 服务器停机 1)如果服务器运行在无持久化的内存模式下,停机之后重启内存中不会有数据,因此数据总是一致的。 2)如果服务器处于AOF或者RBD模式下,那么停机重启之后服务器可以恢复数据,数据也是一致的。 这里需要注意,数据的一致性与持久性的区别,服务器停机重启会有丢数据的可能,但是这不影响数据的一致性,影响的是数据的持久性。 ## 持久性 持久性指的是,当事务执行完成之后,数据已经被持久化到永久介质中了。 1)在无持久化的内存模式下,Redis事务不具备持久性 2)在RBD模式下,服务器只会在特定的条件被满足时再回执行BGSAVE命令,而BGSAVE命令不能保证事务数据被第一时间保存到硬盘,所以也不具备持久性 3)在AOF模式下,并且appendfsync的值为always时,事务具有持久性。AOF模式下,appendfsync为其他值(no,everysec)时不具备持久性 ## WATCH命令的作用 WATCH命令主要用于实现乐观锁即CAS,被WATCH的key,在EXEC命令执行时,如果有其他客户端修改过key对应的值,那么服务器会拒绝事务执行,并返回客户端代表失败的空回复(nil) 比如客户端A和B,A先WATCH了key:name,然后开启了事务,然后向服务器发送了M1,M2,M3三个命令,最后执行EXEC,而客户端B在A客户端WATCH之后,EXEC之前,修改了key:name的值,那么A客户端EXEC将会失败。 另外:EXEC执行之后,所有被WATCH的key都自动UNWATCHED,当然,我们也可以手动UNWATCH ## 总结 1. Redis事务的基本过程:watch监视某些key值,MULTI开启事务,发送命令,最后EXEC执行 2. Redis服务端在收到命令后会把命令入队,收到 EXEC命令会按顺序执行收到的命令 3. Redis命令入队出错,服务端收到EXEC后会拒绝执行; 4. Redis命令执行出错不会影响同一个事务中其他命令的执行; 5. Redis的WATCH命令可以用来实现乐观锁,从而保证事务安全性 6. Redis事务具备原子性,隔离性,一致性,是否具备持久性需要看配置以及运行模式。 7. Redis事务不支持回滚 ## 参考资料 1.《Redis设计与实现》(黄健宏) 2. http://redis.io/topics/transactions
上一篇:
String.replaceAll方法以及java.util.regex.Matcher类的妙用
下一篇:
为什么HashMap要自己实现writeObject和readObject方法?
0
赞
479 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
Please enable JavaScript to view the
comments powered by Disqus.
comments powered by
Disqus
文档导航