Redis事务
Posted 佳716
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis事务相关的知识,希望对你有一定的参考价值。
Redis事务
Redis通过 MULTI 、 EXEC 、 WATCH 等命令来实现事务功能。事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。
1.事务的实现
下面给了一个事务的简单例子:
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set "name" "wangjia06"
QUEUED
127.0.0.1:6379> get "name"
QUEUED
127.0.0.1:6379> set "company" "dianping"
QUEUED
127.0.0.1:6379> get "company"
QUEUED
127.0.0.1:6379> set age 28
QUEUED
127.0.0.1:6379> get age
QUEUED
127.0.0.1:6379> exec
1) OK
2) "wangjia06"
3) OK
4) "dianping"
5) OK
6) "28"
退出一个事务可以用 MULTI 命令, 此时再执行事务会报错:
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get "company"
QUEUED
127.0.0.1:6379> get "age"
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
一个事务包括三个步骤:
- 事务开始:事务以 MULTI 开始,返回OK命令。
- 命令入队:每个事务命令成功进入队列后,返回 QUEUED 。
- 事务执行: EXEC 执行事务。
Redis事务内会遇到两种错误:
- 队列入队不成功:语法错误,错误的命令名字或者一些重要的条件如OOM条件。这种客户端会进行校验,如果入队成功则返回QUEUED ,否则返回错误。如果一个命令入队失败,大多数客户端会终止该事务。
127.0.0.1:6379> get name
"wangjia08"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name "wangjia09"
QUEUED
127.0.0.1:6379> get
(error) ERR wrong number of arguments for ‘get‘ command
127.0.0.1:6379> get name
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
- 命令执行时报错:如对一个String值进行列表操作。所有其他的命令会被正常执行即使在事务执行中一些命令失败。
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set sex man
QUEUED
127.0.0.1:6379> lpop sex
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get sex
"man"
127.0.0.1:6379>
Redis不支持事务回滚功能,原因大概有两点:
- 一个redis命令执行失败,一般是语法错误或者应该在开发阶段被检测出来,而不是在生产环境。
- redis追求简单、速度快,所以不提供事务回滚功能.
2.WATCH命令的实现
watch 命令给redis事务提供了一个 CAS 功能。它是一个乐观锁,检查被监视的健是否至少有一个已经被修改过了,如果是的话拒绝执行,并返回nil代表执行失败。
如下面例子,在一个客户端开启事务前对键“name”进行监视,若在这个事务执行前,另一个客户端修改了键“name”的值,之后事务执行后就会报nil。
127.0.0.1:6379> watch "name"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 10
QUEUED
127.0.0.1:6379> get "name"
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> set "name" "wangjia08"
OK
watch 命令监视多个键:
127.0.0.1:6379> watch "name" "age"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get "name"
QUEUED
127.0.0.1:6379> get "age"
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>
127.0.0.1:6379> set "age" 11
OK
3.事务的ACID性质
- 原子性:redis事务多个操作当做一个整体来执行,要么执行事务中的所有操作,要么一个也不执行。
- 一致性:“一致”指的是数据符合数据库本身的定义和要求,没有包含非法的或无效的错误数据
- 入队错误:服务器拒绝执行该事务。
- 执行错误:出错的命令会被服务器识别出来,并进行相应的错误处理,不会对数据库做任何修改,也不会对数据一致性造成影响。
- 服务器停机: RDB 、 AOF 还原数据库状态
- 隔离性:单线程执行事务,且服务器保证事务期间不会对事务进行中断
- 持久性:当一个事务执行完毕时,执行这个事务所得的结果已经被保存到永久性存储介质(比如硬盘)里面了。Redis事务的持久性由Redis所使用的持久化模式决定(无持久化模式、 RDB 、 AOF )。Redis工作在无持久化模式下时,事务无持久性。在 AOF 模式下 appenfsync 为 no 时,事务也无持久性
以上是关于Redis事务的主要内容,如果未能解决你的问题,请参考以下文章