专栏名称: 互联网后端架构
主要介绍Java后端架构。其中也会掺杂一些前端、GO、Python、Linux,目标:全栈工程师!---好像很牛叉的样子 ^-^
目录
相关文章推荐
架构师之路  ·  想要提升deepseek回复质量,会这一招就 ... ·  2 天前  
51好读  ›  专栏  ›  互联网后端架构

Redis 事务

互联网后端架构  · 公众号  · 架构  · 2017-09-27 12:00

正文

Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability),简称ACID。

我们逐项考察下 Redis 在事务的 ACID 上做出的权衡与取舍:

原子性(Atomicity)

原子意味着操作的不可再分,要么执行要么不执行。Redis 本身提供的所有 API 都是原子操作,那么 Redis 事务其实是要保证批量操作的原子性。Redis 实现批量操作的原理是在一个事务上下文中(通过 MULTI命令开启),所有提交的操作请求都先被放入队列中缓存,在 EXEC 命令提交时一次性批量执行。这样保证了批量操作的一次性执行过程,但 Redis 在事务执行过程的错误情况做出了权衡取舍,那就是放弃了回滚。Redis 官方文档对此给出的解释是:

1. Redis 操作失败的原因只可能是语法错误或者错误的数据库类型操作,这些都是在开发层面能发现的问题不会进入到生产环境,因此不需要回滚。

2.Redis 内部设计推崇简单和高性能,因此不需要回滚能力。

据实而说第一条说法感觉有点站不住脚,可以想象得到 Redis 操作失败的原因绝对不止语法层面的错误,特别是一些像依赖操作系统、文件系统的操作。第二条说法更实在,Redis 的应用场景明显不是为了数据存储的高可靠而设计的,而是为了数据访问的高性能而设计,设计者为了简单性和高性能而部分放弃了原子性。

出于以上考虑 Redis 的事务执行有以下特点:

1. 批量操作在发送 EXEC 命令前被放入队列缓存

2. 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行

3. 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中

一致性(Consistency)

一致性意味着事务结束后系统的数据依然保证一致。在事务开始之前,数据保持有效的状态,事务结束后也如此。显 然在前面讨论原子性时, Redis 舍弃了回滚的设计,基本上也就舍弃对数据一致性的有效保证 。不过对于一个高效的 key-value store 或 data structure server,数据操作一致性很多时候更多应该依赖应用层面,事实也是我们使用 Redis 时很多时候都是分片和集群的,数据一致性无法依靠任何事务机制。

隔离性(Isolation)

隔离性保证了在事务完成之前,该事务外部不能看到事务里的数据改变。也不能访问一些中间状态,因为假如事务终止的话,这些状态将永远不会发生。 Redis 采用单线程设计 ,在一个事务完成之前,其他客户端提交的各种操作都无法执行因此自然没法看见事务执行的中间状态, 隔离性得到保证

持久性(Durability)

Redis 一般情况下都只进行内存计算和操作, 持久性无法保证







请到「今天看啥」查看全文