Redis的事务机制能保证ACID属性吗?

news2024/11/23 8:55:10

目录

事务 ACID 属性

用户如何开启Redis的事务?

使用redis-cli客户端来展示

​Go语言编码使用事务

Redis 的事务机制能保证哪些属性?

1. 原子性

语法错误

运行错误

执行EXEC时,Redis发生故障

Redis对事务原子性属性的保证情况

 2. 一致性

命令入队就错误

命令在实际执行时才报错

EXEC命令执行时,Redis发生故障

3. 隔离性 

4. 持久性

总结


为什么要把这批操作 称为 事务呢?是因为一批操作在执行过程中想获得一些保证。而事务就提供了这些保证。

事务在执行的时候,会提供专门的属性保护,包括原子性、一致性、隔离性和持久性。

事务 ACID 属性

原子性(Atomicity)

事务的整个过程如原子操作一样,最终要么全部成功,或者全部失败,这个原子性是从最终结果来看的,从最终结果来看这个过程是不可分割的。业务应用使用事务时,原子性也是最被看重的一个属性。

一致性(Consistency)
一个事务必须使数据库从一个一致性状态变换到另一个一致性状态,是指数据库中的数据在事务执行前后是一致的。

比如说转账, 用户A余额200元,用户B余额100元,A给B转账100元,事务结束后,用于A余额是100元,用户B余额是200元,这个就是一致性。如果A上的钱减少了,而B上的钱却没有增加,那么我们认为此时数据处于不一致的状态。

隔离性(Isolation)
一个事务的执行不能被其他事务干扰。它要求数据库在执行一个事务时,其它操作无法存取到正在执行事务访问的数据。

比如某件商品库存10件,在一个事务过程中,用户A对该商品下单6件,而另外,用户B也对该商品下单5件,那累加后就超过库存数了,不符合业务要求。所以是,在事务的修改某数据时候,其他的不能修改该数据,但是可以访问该数据,但只能访问到事务开始前的值。这样就是两个进行了隔离。

持久性(Durability)
一个事务一旦提交,他对数据库中数据的改变就应该是永久性的。当事务提交之后,数据会持久化到硬盘,修改是永久性的。

用户如何开启Redis的事务?

事务的执行过程包含3个步骤,Redis提供了MULTI、EXEC两个命令来完成这三个步骤。

  1. 客户端使用 MULTI 命令显式表示开启一个事务
  2. 客户端吧事务中要执行的操作(比如增删改数据)发送给服务端。注意:这些命令虽然被客户端发送到了服务端,但Redis实例只是把这些命令暂存到一个命令队列中,并不会立即执行。
  3. 客户端向服务器发送提交事务的命令 EXEC,让数据库实际执行第二步中发送的具体操作。当服务端收到该命令后,才会真正执行命令队列中的所有命令。

 

使用redis-cli客户端来展示

事务过程中它们执行后的返回结果都是 QUEUED,这就表示,这些操作都被暂存到了命令队列,还没有实际执行。等到执行了 EXEC 命令后,可以看到返回了结果,这就表明,事务中的操作已经成功地执行了。

Go语言编码使用事务

func main() {
	client := redis.NewClient(&redis.Options{
		Addr:     "127.0.0.0.1:6379",
		Password: "", //若是设置了密码,就需要填写
		DB:       0,
	})

	ping, _ := client.Ping().Result()    //测试是否网络通
	fmt.Println(ping)

	//该方法注解//TxPipeline acts like Pipeline, but wraps queued commands with MULTI/EXEC.
	pipe := client.TxPipeline()
	val, _ := pipe.Set("key1", 100, 0).Result()
	fmt.Println("set key1 ", val) //该结果要在执行exec后才会有
	pipe.Set("key2", "200", 0)
	pipe.Get("key2")

	//执行命令队列中的命令
	_, err := pipe.Exec()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("执行exec 后 set key1 ", val)

	value1, err := client.Get("key1").Result()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("key1: ", value1)
}

Redis 的事务机制能保证哪些属性?

1. 原子性

要求是批操作是全部成功或者全部失败。要是在事务过程中,出现了错误,Redis还能保证原子性吗?这个要分三种情况来分析。

语法错误

语法错误指的是命令的参数个数不正确,命令本身拼写错误等情况。

在执行EXEC命令时,客户端发送的操作命令本身就有错误(比如使用了不存在的命令),在命令入队时候就被Redis判断出来。

在命令入队时候,Redis就会报错并记录下该错误。而此时,我们还能继续提交命令。等到执行EXEC之后,Redis就会拒绝执行所有提交的命令操作,返回错误的结果。

这样,事务中的所有命令都不被执行,保证了原子性。

运行错误

运行错误是指输入的命令格式正确,但是在命令执行期间出现了错误。典型的及时命令和操作的数据类型不服务的情况。比如添加一个string类型的key,之后却对该key进行列表操作。

127.0.0.1:6379> set skey ss
OK
127.0.0.1:6379> lpush skey value
(error) WRONGTYPE Operation against a key holding the wrong kind of value

那么,事务操作入队时候,命令和操作的数据类型不匹配,但是Redis没有检查出错误。但是在执行完EXEC之后,Redis实际执行这些操作时候,会报错。但是,注意:Redis对错误命令报错,但还是会把正确的命令执行完。在这种情况下,事务的原子性就无法得到保证。

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set score 100
QUEUED
127.0.0.1:6379(TX)> lpush score 200
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value

上面的例子,命令和操作的数据类型不匹配的时候,set命令成功了,而lpush失败了。这个事务的原子性就没有得到保证。

DISCARD命令

到这里,你可能会疑惑,传统数据库(比如MySQL)在z执行事务的时候,会提供回滚机制,当事务执行发生错误的时候,事务中的所有操作都会被撤销,已经被修改的数据也会被恢复到事务执行前的状态。那么,在上面的例子中,若命令实际执行时报错了,是不是可以用回滚机制来恢复原来的数据呢?

其实,Redis没有提供回滚机制。Redis提供了DISCARD命令,但是,这个命令只能用来主动放弃事务执行,把暂存的命令队列情况,没起到回滚的效果。

执行EXEC时,Redis发生故障

事务的命令都是放入到一个命令队列中的,那么执行exec时候,执行了该事务的一半命令,而Redis出现故障,那这一半命令是执行成功的了。但是Redis出故障重启后,就需要通过RDB或者AOF文件去恢复数据。

  • AOF模式:现在一般都是开启AOF的,若开启了AOF的, Redis会首先去找AOF文件恢复数据。首先,这个事务的一半命令的操作记录是被记录到AOF日志中的了。但是这个事务是未完成的。使用redis-check-aof工具检测 AOF 日志文件,可以把未完成的事务操作从 AOF 文件中去除。这样一来,使用 AOF 文件恢复实例后,这个事务不会被再执行,从而保证了原子性
  • RDB模式:若是只使用RDB模式,在执行事务时,Redis 不会中断事务去执行保存 RDB 的工作,只有在事务执行之后,保存 RDB 的工作才有可能开始。即是最新的 RDB 快照是在当前 EXEC 执行之前生成的。所以当 RDB 模式下的 Redis 服务器进程在事务中途出故障时,事务内执行的命令,不管成功了多少,都不会被保存到 RDB 文件里。通过RDB文件去恢复,这样就不会再次执行该事务的命令语句,从而保证了原子性。
  • 不开启AOF和RDB:重启后内存中的数据就会全部丢失,也就谈不上原子性了。

Redis对事务原子性属性的保证情况

  • 命令入队时就报错,会放弃事务执行,保证原子性;
  • 命令入队时没有报错,在实际执行时报错,不保证原子性;
  • exec命令执行时,Redis实例故障,若开启了AOF或者RDB,可以保证原子性。

 

 2. 一致性

其会受到错误命令、实例故障的影响。有三种情况:

命令入队就错误

在这种情况下,事务本身就会被放弃执行,那么就可以保证数据库的一致性。

命令在实际执行时才报错

在这种情况下,有错误的命令不会被执行,正确的命令可以正常执行,所以也不会改变数据库的一致性。

EXEC命令执行时,Redis发生故障

故障后进行重启,就会使用RDB或AOF文件来恢复数据。

  • 纯内存模式。即是没有开启RDB或者AOF,,那实例故障重启后,数据就都没有了,数据库是一致的。
  • 使用RDB快照模式。因为RDB快照不会在事务执行时执行,所以,事务命令的操作不会被保存到RDB快照中。使用RDB恢复时候,数据库里的数据也是一样的。
  • 使用AOF。而事务操作还没有被记录到AOF日志时(即是命令已经有执行一条的,当时该记录还没有写入到磁盘中),实例就发生故障。所以使用AOF日志恢复的数据库日志时一致的。若是只有部分操作被记录到了AOF日志,我们可以使用 redis-check-aof 清除事务中已经完成的操作,数据库恢复后也是一致的。

所以,总结来说,在命令执行错误或 Redis 发生故障的情况下,Redis 事务机制对一致性属性是有保证的。

 

3. 隔离性 

这个属性有讲究。一开始时候,我认为Redis的执行命令部分是单线程的,那就是串行化,那肯定是有隔离性保障的。但是却不是这么简单的。

看一个场景,商品库存是10,用户A开启事务,把库存-5的操作存入到命令队列中,这时用户B把库存-5,这个操作是即刻执行的。那在真正执行事务命令前,库存就是3了。之后exec,那库存再-5,那就不符合业务要求的,那就是没有隔离性。

所以, 不是说是单线程执行命令就是有隔离性保证的了。

Redis的隔离性保证,会受到和事务一起执行的并发操作的影响。而事务执行又可以分成 命令入队(exec命令执行前)命令实际执行(exec命令执行后) 两个阶段。

  • 并发操作在exec命令执行前,隔离性的保证要使用watch机制来实现,否则无隔离性(就是上面的例子)。
  • 并发操作在exec命令后,此时,隔离性可以保证。

那要讲讲watch机制。其作用是,在事务真正执行前,监控该事务会操作的一个或多个键的变化情况,当事务调用exec执行时,watch机制会先检查监控的键是否被其他客户端修改了,若是修改了,就放弃事务执行,避免事务的隔离性被破坏。然后,客户可以再次执行事务,若此时没有并发修改数据的操作了,事务就能正常执行,隔离性也得到了保证。

watch机制,对于用户来说,就是使用watch命令,当时需要用户主动显性使用watch监听想要操作的键。比如上面的事务是想要操作键shop,所以就需要在mutli之前执行 watch shop。

执行exec时候,返回nil,表示放弃事务执行。这样一来,事务的隔离性就可以得到保证了。

而另一种情况:并发操作在 EXEC 命令之后被服务器端接收并执行

这个就简单多了。因为Redis执行命令部分是单线程的,而且,exec命令执行后,Redis会保证先把命令队列中的命令执行完,之后才执行并发收到的命令。所以这时并发操作,不会影响到事务命令执行。所以,在该情况下,并发操作并不会破坏事务的隔离性。

 

4. 持久性

Redis是内存数据库,所以,其数据是否持久化保存是完全取决于Redis的持久化配置模式。

  • 没有使用RDB或者AOF,事务的持久性肯定是得不到保证的。
  • 使用RDB模式。在一个事务执行后,下一次的 RDB 快照还未执行前,如果发生了实例宕机,事务的持久性同样无法保证;
  • 使用 AOF 模式。AOF 模式的三种配置选项 no 、everysec 都会存在数据丢失的情况 。always 可以保证事务的持久性,但因为性能太差,在生产环境一般不推荐使用。

综上,redis 事务的持久性是无法保证的 。 

总结

Redis使用 multi、exec、discard、watch 四个命令来支持事务机制。

  • multi :开启一个事务
  • exec :提交事务,从命令队列中取出提交的操作命令,进行实际执行
  • discard : 放弃一个事务,清空命令队列
  • watch :检测一个或多个键的值在事务执行过程中是否发生变化,若发生变化,当前事务就放弃执行

Redis的事务机制可以保证一致性隔离性一定程度的原子性(不提供回滚),无法保证持久性。 

原子性的情况比较复杂,只有当事务中使用的命令执行时有误(即是入队无误,执行时刻有误),原子性得不到保证,其他情况下,事务都可以原子性执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1635203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图论单源最短路径——spfa

【模板】单源最短路径(弱化版) 本题用的spfa 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779。 题目描述 如题,给出一个有向图,请输出从某一点出发到…

想要接触网络安全,应该怎么入门学习?

作为一个网络安全新手,首先你要明确以下几点: 我刚入门网络安全,该怎么学?要学哪些东西?有哪些方向?怎么选?这一行职业前景如何? 其次,如果你现在不清楚学什么的话&…

【GESP试卷】2024年03月Scratch二级试卷

2024年GESP03月认证Scratch二级试卷 分数:100 题数:17 一、单选题(共10题,每题3分,共30分) 1、小杨的父母最近刚刚给他买了一块华为手表,他说手表上跑的是鸿蒙,这个鸿蒙是?( &…

2024最新UI发卡盗U/支持多语言/更新UI界面/支持多个主流钱包

本文来自:2024最新UI发卡盗U/支持多语言/更新UI界面/支持多个主流钱包 - 源码1688 应用介绍 简介: 2024最新UI发卡盗U/支持多语言/更新UI界面/支持多个主流钱包 自行检查后门,最好是部署智能合约后用合约地址来授权 包含转账支付页面盗U授…

[C++][算法基础]最大不相交区间数量(贪心 + 区间问题2)

给定 𝑁 个闭区间 [𝑎𝑖,𝑏𝑖],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。 输出可选取区间的最大数量。 输入格式 第一行包含整数 &#x1d4…

情感类ppt素材

小清新手绘插画风毕业季毕业相册同学录画册纪念册PPT下载 - 觅知网这是一张关于清新毕业相册的PPT模板,清新风格设计,加上风为装饰元素,包含毕业相册、毕业季、毕业、同学、纪念等主题内容,也可用作毕业相册PPT、毕业季PPT、毕业P…

网络安全等级保护定级指南PPT解读

新版网络安全等级保护定级指南网络安全等级保护工作的作用对象,主要包括基础信息网络、工业控制系统、云计算平台、物联网、使用移动互联技术的网络和大数据等。 软件全套精华资料包清单部分文件列表: 工作安排任务书,可行性分析报告&#xf…

一个代码搞定显著差异柱状图和箱线图 | R语言绘图

本教程原文链接:一个代码搞定显著差异柱状图和箱线图 | R语言绘图 本期教程 小杜的生信笔记,自2021年11月开始做的知识分享,主要内容是R语言绘图教程、转录组上游分析、转录组下游分析等内容。凡事在社群同学,可免费获得自2021年…

Python新手入门基础英文笔记

1、字符串的操作 user:用户 name:名称/姓名 attibute:字段/属性 Value:值 2、重复/转换/替换/原始字符号 upper:上面 lower:下面 capitalize:用大写字母写或印刷 title:标题…

读懂一本书笔记

文章目录 引言 我是一个用读书改变自己生活的人01 会读书,更要会讲书复杂时代,阅读是大众反脆弱的武器你焦虑吗?如何从“单向度的人”变为“多向度的人”第一,读书是主动的学习方式第二,读书是有针对性的学习方式 讲书…

OpenCV如何实现拉普拉斯算子的离散模拟

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV的Sobel 衍生品 下一篇 :OpenCV 如何实现边缘检测器 目标 在本教程中,您将学习如何: 使用 OpenCV 函数 Laplacian() 实…

智慧农场系统 搭建重点,会用到哪些三方服务?

智慧农场小游戏的搭建重点主要集中在游戏设计、用户体验、数据安全和稳定性等方面。为了实现这些目标,可能会用到以下第三方服务: 游戏引擎和开发工具:使用成熟的游戏引擎和开发工具可以极大地简化开发流程,提高开发效率。例如&a…

一文了解单链表

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、单链表是什么?二、单链表功能函数实现1.申请节点2.尾插3.头插4.尾删5.头删6.查找7.在指定位置前插入数据8.在指定位置后插入数据9.删除指定位置…

中国移动举办算力网络未来产业暨联合体创新论坛

4月29日,在国务院国有资产监督管理委员会的指导下,由中国移动主办的算力网络未来产业暨联合体创新论坛在苏州举办。大会以“算网一体,智领未来”为主题,旨在汇聚算力网络产学研各界领军力量,共创算力网络技术策源之路&…

大规模SLAM技术

书籍:Large-Scale Simultaneous Localization and Mapping 作者:Janusz Bğdkowski 出版:Springer 书籍推荐-《大规模SLAM技术》书籍:Large-Scale Simultaneous Localization and Mapping作者https://mp.weixin.qq.com/s/XopFq…

私域卖酒_私域卖酒怎么做

坐标:厦门,我是易创客运营肖琳 深耕社交新零售行业10年,主要提供新零售系统工具及顶层商业模式设计、全案策划运营陪跑等。 链动21模式为酒业企业带来了革命性的变革,通过与消费者建立紧密联系,实现了个性化定制的精…

mysql基础知识汇总

本文自行整理,只做学习记忆之用,若有不当之处请指出 一、数据库三层结构 (1)所谓安装Mysql数据库,就是在主机安装一个数据库管理系统(DBMS),这个管理程序可以管理多个数据库。DBMS(database manage system) &#xf…

数据结构八:线性表之循环队列的设计

上篇博客,学习了栈,我们可以知道他也是一种线性表,遵从先进后出的原则,在本节,我们进一步学习另一种线性表—队列。就像饭堂里排队打饭的的队伍,作为一种先进先出的线性表,他又有哪些特别之处呢…

什么是域名解析?域名解析的完整流程是什么?如何清理DNS缓存?(附源码)

目录 1、什么是域名? 2、为什么使用域名? 3、域名解析的完整流程 4、调用gethostbyname系统接口将域名解析成IP地址 5、为什么需要清理系统DNS缓存? 6、使用cmd命令清理DNS缓存 7、通过代码去清除系统DNS缓存 C软件异常排查从入门到精…

2024年度四川省重点实验室资助申报范围重点、时间方式

一、申报范围 (一)本项目面向文化和旅游部重点实验室开展申报。 (二)申报项目应围绕实验室研究方向,解决行业重要共性关键技术或基础研究问题,着力提升实验室科技支撑能力和人才培养能力。支持重点包括&a…