您的位置:首页 > 数据库 > Redis

redis 事务特性

2016-03-30 00:00 393 查看
摘要: redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。 由于redis是单线程来处理所有client的请求的所以做到这点是很容易的。一般情况下redis在接受到一个client发来的命令后会立即处理并 返回处理结果,但是当一个client在一个连接中发出multi命令有,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一 个队列中。当从此连接受到exec命令后,redis会顺序的执行队列中的所有命令。并将所有命令的运行结果打包到一起返回给client,然后结束事务上下文。

Redis 事务

redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。 由于redis是单线程来处理所有client的请求的所以做到这点是很容易的。一般情况下redis在接受到一个client发来的命令后会立即处理并 返回处理结果,但是当一个client在一个连接中发出multi命令有,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一 个队列中。当从此连接受到exec命令后,redis会顺序的执行队列中的所有命令。并将所有命令的运行结果打包到一起返回给client,然后结束事务上下文。

Redis 事务特性

数据ACID特性满足了几条?
为了保持简单,redis事务保证了其中的一致性和隔离性;
不满足原子性和持久性;

原子性

redis事务在执行的中途遇到错误,不会回滚所有的命令,而是继续执行后续命令;(违反原子性)
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作;
中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做;

示例:
127.0.0.1:6379> set b 11 # 设置 b 对应的 value 为字符串类型
OK
127.0.0.1:6379> multi # 开启事物
OK
127.0.0.1:6379> sadd a aa aaa # 添加一个 set key 为 a
QUEUED
127.0.0.1:6379> sadd b bb bbb # 添加一个 set key 为 b,此时因为 b 对应的 key 已被占用,而且对应的数据类型为 string,所以这里会失败
QUEUED
127.0.0.1:6379> sadd c cc ccc # 添加一个 set key 为 c
QUEUED
127.0.0.1:6379> exec # 提交事务,两个成功一个失败,并没有全部回滚
1) (integer) 2
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) (integer) 2
127.0.0.1:6379> SMEMBERS a
1) "aa"
2) "aaa"



持久性

事务不过是用队列包裹起了一组 Redis 命令,并没有提供任何额外的持久性功能,所以事务的持久性由 Redis 所使用的持久化模式决定:

在单纯的内存模式下,事务肯定是不持久的。

在 RDB 模式下,服务器可能在事务执行之后、RDB 文件更新之前的这段时间失败,所以 RDB 模式下的 Redis 事务也是不持久的。

在 AOF 的“总是 SYNC ”模式下,事务的每条命令在执行成功之后,都会立即调用 fsync 或 fdatasync 将事务数据写入到 AOF 文件。但是,这种保存是由后台线程进行的,主线程不会阻塞直到保存成功,所以从命令执行成功到数据保存到硬盘之间,还是有一段非常小的间隔,所以这种模式下的事务也是不持久的。

其他 AOF 模式也和“总是 SYNC ”模式类似,所以它们都是不持久的。

隔离性和一致性

redis事务在执行的过程中,不会处理其它命令,而是等所有命令都执行完后,再处理其它命令(满足隔离性)
redis事务在执行过程中发生错误或进程被终结,都能保证数据的一致性;

事务操作示例

正常的提交事务



事务回滚



乐观锁



另一个 client 修改 watchkey 的值,导致主窗口的事务提交失败

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  redis 事务