标签:
一、概述
和其他数据库一样,Redis 同样是支持事务的。Redis 的事务可以通过 MULTI/EXEC/DISCARD/WATCH 四个命令来实现。那么 Redis 的事务有哪些特点呢?
1). 事务是一个原子操作,事务中的命令要么都执行,要么都不执行。
2). 事务中的所有命令将按照顺序依次执行。
3). Redis 事务不支持回滚,当事务中的某条命令执行失败的时候,会继续执行下条命令,直至事务结束。
不支持回滚有何优势呢? - 不需要支持回滚,Redis 内部可以保持简单而快速。
不支持回滚是否合理? - 合理,事务执行过程中,Redis 命令只会因为错误的语法而失败,而失败的命令是编程造成的,这些错误应该在开发过程中被发现,而不应该出现在生产环境中。
二、相关命令的用法
1). multi 与 exec:multi 用于开启事务,总是返回 ok。multi 执行后,后面的命令暂时不会执行,而是会存到队列中,等到 exec 执行之后,队列中的命令才会依次序执行。例子如下:
2). discard 始终返回 ok,会清空事务队列,并且放弃执行事务。例子如下:
3). watch 命令可以监视多个 key,事务只能在这些 key 没有被修改的情况下执行,如果这个前提不能满足的话,事务就不会执行。返回值为 ok。
对 key 的监视从调用 watch 开始生效,直到调用 exec 为止。exec 被调用的时候不管事务是否执行,都会取消对 key 的监视。另外当客户端断开连接后也会取消监视。
使用无参数的 unwatch 可以取消对所有 key 的监视。
三、Redis 怎样处理事务中的错误
首先,应该分为两类错误:
1). exec 之前的错误;比如入队的命令语法参数数量错误,参数名错误等(入队时就能检查出错误来)。
处理方式:Redis 会对入队失败的命令进行记录,当调用 exec 的时候,自动拒绝执行并放弃这个事务。
例子如下:incr mykey 1 入队失败,因为参数不正确。
2). exec 之后的错误;比如事务中处理集合的命令用在了字符串上面(只有在执行的时候才会报错)。
处理方式:事务中的命令执行失败,继续执行下一条命令,直至事务结束。
例子如下:lpop mykey 报错,作用于 list 类型,不能用于字符串;但是不影响后续命令执行,+1 操作依然执行成功。
四、watch 命令与 CAS 乐观锁
当多个客户端同时对同一个 key 进行 INCR(+1) 操作时, 就会产生竞争条件。举个例子,如果客户端 A 和 B 都读取了键原来的值为 10,那么两个客户端都会将键的值设为 11,但正确的结果应该是 12 才对。
而 watch 命令可以解决这个问题:在进行事务操作之前,用 watch 命令监视这个 key,如果别的客户端对这个 key 做了修改,那么我的客户端的事务就会执行失败。这就是乐观锁。
标签:
原文地址:http://www.cnblogs.com/xmsx/p/5387027.html