2022/12/26 请你谈谈数据库事务机制?

news2024/11/24 3:29:34

1 事务四大特征

一般来说,事务是必须满足4个条件(ACID):原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

事务是最小的执行单位,不允许分割。

原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。(比如:A向B转账,不可能A扣了钱,B却没有收到)

隔离性:数据库允许多个并发事务同时对其数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。

持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

总的来说,InnoDB存储引擎的原子性是通过undo log来保证,事务的持久性是通过redo log来实现的,事务的隔离性是通过读写锁+MVCC机制来实现的。而原子性、持久性、隔离性都只是手段,其目的是为了实现一致性,MySQL满足的是其自身内部数据的一致性,而对于具体业务的一致性,还需要应用程序本身遵守一致性规约。

MySQL事务实现的机制是WAL(Write-ahend logging,预写式日志),这是比较主流的方案。

在MySQL服务异常崩溃后,使用WAL,可以在系统重启之后,通过比较日志和系统状态来决定继续之前的操作或者是撤销之前的操作。

redo log(重做日志):每当操作时,在磁盘数据变更之前,将操作写入redo log,这样当系统奔溃重启后可以继续执行。

undo log(回滚日志):当一个事务执行一半无法继续执行时,可以根据回滚日志将之前的修改恢复到变更之前的状态。

2 undo log && redo log 的理解?

2.1 undo log

回滚日志,在数据库事务开始之前,MYSQL会去记录更新前的数据到undo log文件中。如果事务回滚或者数据库崩溃时,可以利用undo log日志中记录的日志信息进行回退。

undo log生命周期:

undo log产生: 在事务开始之前
undo log销毁: 当事务提交之后
undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo log 段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。
注意: undo log也会生产redo log,undo log也要实现持久性保护。

undo log是逻辑日志,实现事务的原子性。undo log记录的是事务[开始前]的数据状态,记录的是更新之前的值。

1、undo log日志可以实现事务的回滚操作
我们在进行数据更新操作的时候,不仅会记录redo log,还会记录undo log,如果因为某些原因导致事务回滚,那么这个时候MySQL就要执行回滚(rollback)操作,利用undo log将数据恢复到事务开始之前的状态。

如我们执行下面一条删除语句:

delete from book where id = 1;

那么此时undo log会生成一条与之相反的insert 语句【反向操作的语句】,在需要进行事务回滚的时候,直接执行该条sql,可以将数据完整还原到修改前的数据,从而达到事务回滚的目的。

再比如我们执行一条update语句:

update book set name = "三国" where id = 1;   ---修改之前name=西游记

此时undo log会记录一条相反的update语句,如下

update book set name = "西游记" where id = 1;

如果这个修改出现异常,可以使用undo log日志来实现回滚操作,以保证事务的一致性。
在这里插入图片描述
如上图所示:
当事务A进行一个update操作,将id=1修改成id=2。首先会修改buffer pool中的缓存数据,同时会将旧数据备份到undo log buffer中,记录的是还原操作的sql语句。此时如果事务B要查询修改的数据,但是事务A还没有提交,那么事务B就会从undo log buffer中,查询到事务A修改之前的数据,也就是id=1。此时undo log buffer会将数据持久化到undo log日志中(落盘操作)。undo日志持久化之后,才会将数据真正写入磁盘中,也就是写入ibd的文件中。最后才会执行事务的提交。

在这里插入图片描述

2.2 redo log

https://blog.csdn.net/zs18753479279/article/details/127245352

3 事务的隔离级别

在这里插入图片描述
READ UNCOMMITTED 读取未提交内容:在这个隔离级别,所有事务都可以"看到"未提交事务的执行结果。

READ COMMITTED 读取提交内容:大多数数据库系统的默认隔离级别(但是不是MySQL的默认隔离级别),一个事务从开始到提交前,所做的任何数据改变都是不可见的,除非已经提交。这种隔离级别会导致“不可重复读"。这意味着用户运行同一个语句两次,看到的结果是不同的。

REPEATABLE READ 可重复读:MySQL数据库默认的隔离级别。这种隔离级别可以避免“不可重复读取”,达到可重复读取,不过这会导致另外一个棘手问题”幻读"。通过多版本并发控制机制解决了幻读问题。

SERIALIZABLE可串行化:该级别是最高级别的隔离级。它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简而言之,SERIALIZABLE是在每个读的数据行上加锁。在这个级别,可能导致大量的超时Timeout和锁竞争Lock Contention现象。

脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个修改后的数据。

不可重复读(前后多次读取,数据内容不一致)是指在一个事务内,多次读同一数据。在一个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)

幻读(前后多次读取,数据总量不一致)幻读是一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

3.1 不可重复读和幻读到底有什么区别呢?

(1)不可重复读是读取了其他事务更改的数据,针对update操作
解决:使用行级锁,锁定该行,事务A多次读取操作完成后才释放该锁,这个时候才允许其他事务更改刚才的数据。

(2)幻读是读取了其他事务新增的数据,针对insert与delete操作
解决:使用表级锁,锁定整张表,事务A多次读取数据总量之后才释放该锁,这个时候才允许其他事务新增数据。

幻读和不可重复读都是指的一个事务范围内的操作受到其他事务的影响了。只不过幻读是重点在插入和删除,不可重复读重点在修改。

4 事务实现方式-MVCC(多版本并发控制)

MVCC是MySQL的的多版本并发控制即multi-Version Concurrency Controller,数据库并发场景有三种,分别为:

1、读读:不存在任何问题,也不需要并发控制
2、读写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读、幻读、不可重复读
3、写写:有线程安全问题,可能存在更新丢失问题

MVCC是一种用来解决读写冲突的无锁并发控制,也就是为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照,所以MVCC可以为数据库解决以下问题:

1、在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并
发读写的性能;
2、解决脏读、幻读、不可重复读等事务隔离问题,但是不能解决更新丢失问题。

MVCC最大的好处:读不加锁,读写不冲突,极大的增加了系统的并发性能。

两种读的方式:

1快照读:读取的是历史版本的记录; SQL语句:select …
2当前读:读取的是最新版本的记录;SQL语句:1select … lock in share mode; 2select … for update; 3 update 4 delete 5 insert;

引例:

事务A事务B
selectselect
update -> commit
select (可以读到最新版本的记录吗?)

RC: 是可以读到的
RR: 是读不到的 --------> 为什么?引出MVCC(多版本的并发控制机制)【可见性算法】

4.1 MVCC实现原理是什么?

mvcc的实现原理主要依赖于记录中的三个隐藏字段,undo log,readView来实现的。

4.1.1隐藏字段

行记录都会包括用户看不到隐藏字段:

{
1.DB_TRX_ID:最后一次创建修改该记录的事务ID
2.DB_ROW_ID:隐藏的主键ID
3.DB_ROLL_PTR:回滚指针+undo log
}

4.2 对undo log的理解

undo log被称之为回滚日志,数据历史版本的状态。
在这里插入图片描述

…依次,形成一个链表:当不同的事务对同一条数据修改,会导致该记录的undo log形成一个线性链表,其中链表首部:最新的历史版本记录。链表尾部:多个历史版本最早的历史记录。

4.3 readView

Read View是事务进行快照读操作的时候生产的读视图,Read View的最大作用是用来做可见性判断的,也就是说当某个事务在执行快照读的时候,对该记录创建一个Read View的视图,把它当作条件去判断当前事务能够看到哪个版本的数据,有可能读取到的是最新的数据,也有可能读取的是当前行记录的undo log中某个版本的数据。

事务进行快照读,产生的视图。主要包括以下字段:

{
1.trx_list: 系统活跃的事务ID
2.up_limit_id:列表中最小的事务ID
3.low_limit_id:系统尚未分配的下一个事务ID
}

实际场景:

事务1事务2事务3事务4
开启开启开启开启
update
快照读(能不能读取到修改的记录值)
{
1.trx_list: 1,2,3
2.up_limit_id:1
3.low_limit_id:5
}

DB_TRX_ID:4

这里引入一个算法:

1、首先比较DB_TRX_ ID < up_ limit_ id,如果小于,则当前事务能看到
DB_ TRX_ ID所在的记录,如果大于等于进入下一个判断;

2、接下来判断DB_ TRX_ ID >= low_ limit id,如果大于等于则代表
DB_ TRX_ ID所在的记录在Read View生成后才出现的,那么对于当前事
务肯定不可见,如果小于,则进入下一步判断;

3、判断DB_TRX_ ID是否在活跃事务中:
如果在,则代表在Read View生成时刻,这个事务还是活跃状态,还没有commit, 修改的数据,当前
事务也是看不到;
如果不在,则说明这个事务在Read View生成之前就已经开始commit,那么修改的结果是能够看见的。

所以,快照读是可以读到最新的记录。

4.4 这里解释两个重要概念:RC&&RR

因为Read View生成时机的不同,从而造成RC、RR级别下快照读的结果的不同。

1.在RR级别下的某个事务对某条记录的第一次快照读会创建一个快照即Read View:将当前系统活跃的其他事务记录起来,此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个Read View,所以对之后的修改不可见。

3、在RC级别下,事务每次快照读都会新生成一个快照和Read View,这就是我们在RC级别下的事务中可以看到别的事务提交的更新的原因。

总结:在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View,之后的快照读获取的都是同一个Read View.

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

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

相关文章

软件测试工程职场发展细谈

前言 今天几个测试圈子的大佬约了饭局&#xff0c;席间彼此交流了很多关于职场工作上测试相关的话题&#xff0c;听了他们的一些观点很有启发&#xff0c;我自己对于聊的话题也做了一些描述和实际的案例说明。下面是聊的一些关键话题&#xff0c;我将交流的内容和个人观点整理…

(二)JavaScript

JavaScript 是一门跨平台、面向对象的脚本语言。JavaScript 是用来控制网页行为的&#xff0c;它能使网页可交互。 一、JavaScript 引入方式&#xff08;P71&#xff09; &#xff08;1&#xff09;内部脚本&#xff1a;将JS代码定义在HTML页面中 &#xff08;2&#xff09;外部…

ActiveMQ集群模式

目录 一、面试题 二、多节点集群是什么 三、zookeeperreplicated-leveldb-store的主从集群 四、官网集群原理图 五、部署规划和步骤 六、集群可用性测试 一、面试题 引入消息队列之后该如何保证其高可用性 二、多节点集群是什么 基于ZooKeeper和LevelDB搭建ActiveMQ 集…

API签名鉴权设计

鉴权作用 在实际的业务中&#xff0c;必然会存在和其他平台系统进行数据传输。这个时候出于对数据的保密要求&#xff0c;都会对接口&#xff08;API&#xff09;添加鉴权机制&#xff0c;识别调用方的真实身份&#xff0c;对未通过鉴权的请求不做任何业务处理&#xff0c;以帮…

国科大模式识别导论作业3:神经网络

目录题目代码data.pyutils.pynetwork.pymain.py结果整理一下近期作业中的编程题&#xff0c;仅供交流学习题目 本题使用的数据如下&#xff1a; 第一类 10 个样本&#xff08;三维空间&#xff09;&#xff1a; [ 1.58, 2.32, -5.8], [ 0.67, 1.58, -4.78], [ 1.04, 1.01, -3…

OpenCV 图像旋转、平移、缩放

本文是 OpenCV图像视觉入门之路的第7篇文章&#xff0c;本文详细的进行了图像的缩放 cv2.resize()、旋转 cv2.flip()、平移 cv2.warpAffine()等操作。 OpenCV 图像旋转、平移、缩放目录 1 缩放图片 2 翻转图片 2.1 垂直翻转 2.2 水平翻转 2.3 水平垂直翻转 ​编辑 3 平移…

百度离线人脸识别SDK

1&#xff0c;采坑备忘 &#xff08;1&#xff09;8.1版本的SDK在spring-boot接口访问第一次正常&#xff0c;第二次之后JVM会奔溃&#xff0c;可能是java gc 处理C开出的内存有问题。 换6.1.3版本的SDK。 javaWindows百度离线人脸识别SDK6.1.3-Java文档类资源-CSDN下载javaW…

Harmony/OpenHarmony应用开发-转场动画页面间转场

在全局pageTransition方法内配置页面入场和页面退场时的自定义转场动效。 说明&#xff1a;从API Version 7开始支持。开发语言ets. 名称 参数 参数描述 PageTransitionEnter { type: RouteType, duration: number, curve: Curve | string, delay: number } 设置当前页面…

1998-2014年企业绿色发展数据库

1998-2014年工业企业的排放排污和环境治理等信息数据 1、时间&#xff1a;1998-2014年 2、数据来源&#xff1a;原环保部。 3、统计字段&#xff1a;主要有企业基本信息、生产信息、水环境、大气环境&#xff0c;内容涵盖了资源利用类指标&#xff08;工业用水量、煤炭消费量…

YGG 与 Thirdverse 达成合作,将《足球小将》IP 带入 Web3

YGG 与 Thirdverse 建立了合作关系&#xff0c;Thirdverse 是一家专注于多人 VR 和 Web3 游戏的游戏工作室&#xff0c;在日本和美国分别设有办事处。 YGG 通过购买未来股权的简单协议&#xff08;SAFE&#xff09;参与了 Thirdverse 近期的 1500 万美元融资。这种合作关系将使…

FastAPI从入门到实战(16)——依赖项

依赖注入是耳熟能详的一个词了&#xff0c;听起来很复杂&#xff0c;实际上并没那么复杂&#xff0c;正常的访问需要接受各种参数来构造一个对象&#xff0c;依赖注入就变成了只接收一个实例化对象&#xff0c;主要用于共享业务逻辑、共享数据库连接、实现安全、验证、权限等相…

原油投资怎么样赚钱?原油投资赚钱技巧有哪些?

以前没有交易过原油的投资者&#xff0c;看到其他投资者从中获得了较好的盈利&#xff0c;也想通过原油投资来赚钱。那么原油投资到底能不能赚钱&#xff0c;是很多新手投资者比较想了解的问题。其实原油投资想盈利并不能全部依靠运气&#xff0c;只有掌握了原油投资赚钱技巧&a…

【Java基础】Java日志—什么是日志级别?如何配置数据源到不同的位置?配置文件内容都是什么含义?

目录 一、log4j1详情&#xff1a;记录器和日志级别 二、 log4j1详情&#xff1a;输出源【输出到不同的位置】 1、ConsoleAppender【将日志输出到控制台】 2、FileAppender【将日志输出到文件】 3、DailyRollingFileAppender【每日输出到一个新文件】 4、JDBCAppender【输…

FineReport开源报表系统-JS实现切换Tab块时进行数据联动

1. 概述 1.1 预期效果 在决策报表中&#xff0c;希望 Tab 块轮播切换时&#xff0c;可实现与报表块的数据联动。如下图所示&#xff1a; 1.2 实现思路 通过 JS 获取每个 Tab 块的轮播标题&#xff0c;转换为参数值&#xff0c;再通过控件进行界面传参&#xff0c;实现联动效果…

程序员工作五年后一般会怎样?

最近看到一些吐血言论“一个程序员工作5年后还没成为大牛&#xff0c;是不是该考虑别的路子了&#xff1f;”还有“程序员入行五年&#xff0c;有可能攒够80吗&#xff1f;”不是&#xff0c;程序员工作五年&#xff0c;是戳中了谁的痛点吗&#xff1f;&#xff1f;大家对五年经…

128页4万字某智慧能源集团数字化管理平台项目建议书

【版权声明】本资料来源网络&#xff0c;仅用于行业知识分享&#xff0c;供个人学习参考&#xff0c;请勿商用。【侵删致歉】如有侵权请联系小编&#xff0c;将在收到信息后第一时间进行删除&#xff01;完整资料领取见文末&#xff0c;部分资料内容&#xff1a; 方案设计 在当…

公司新来的软件测试工程师接私活被抓了,难怪他天天加班到凌晨

昨天和我一起进公司的测试部门同事上班接私活被老板抓了&#xff0c;这人才来不到两个月&#xff0c;每天加班到凌晨。刚开始还以为他是个卷王&#xff0c;没想到此人上班时间接单&#xff0c;用加班时间来完成公司需求&#xff0c;造成努力的假象。被老板在办公室骂了俩小时&a…

v$asm_disk中free_mb低于300m导致加盘报ora-15041

背景&#xff1a; 某项目扩容加盘到磁盘组中报磁盘组空间耗尽的错误&#xff0c;如下 明明是加盘&#xff0c;却报空间不足的错误&#xff0c;令人费解 报错的磁盘组为normal冗余&#xff0c;且Usable_file_MB为负&#xff0c;且Free_MB剩余很少或为0 问题排查&#xff1a; …

MS 训练笔记【2】:nnFormer

文章目录前言1. 安装2. 训练与测试2.1. 数据处理2.1.1. 整理数据路径2.1.2. 设置 nnFormer 读取文件的路径2.1.3. 数据集预处理2.2. 训练2.2.1. 训练代码2.2.2. 可能出现的问题及解决办法2.3. 预测总结前言 本文主要记载 nnFormer 从安装到训练再到推理的过程。nnFormer 的环境…

invokeBeanFactoryPostProcessors的理解

invokeBeanFactoryPostProcessors的理解 Spring中有两个非常重要的扩展点&#xff1a; BeanFactoryPostProcessorBeanPostProcessor 其中第一个是可以对BeanDefinition注册时进行扩展&#xff0c;而第二个是对spring中IOC容器中的对象进行实例化的时候进行扩展。 今天主要谈一…