mysql的事务,你弄懂了吗?(Innodb)

news2024/9/21 18:46:20

目录

1.事务的ACID原则

2. 事务的隔离级别

2.1 数据库的脏读问题

2.2 数据库不可重复读问题

2.3 数据库幻读问题

2.4 数据库脏写问题

3.Mysql的锁

3.1 以锁粒度的维度划分

3.2 以互斥性的维度划分:

3.3 以操作类型的维度划分:

3.4 以加锁方式的维度划分:

3.5 以思想的维度划分:

4. 多版本并发控制

4.1回滚日志(Undolog)

4.2 重做日志(redolog)

4.3 MVCC

4.4 ReadView读视图


1.事务的ACID原则

原子性(Atomicity):当前事务的操作要么同时成功,要么同时失败。原子性由undo log 日志实现。

一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。简言之:一个事务中的所有操作,要么一起改变数据库中的数据,要么都不改变,对于其他事务而言,数据的变化是一致的。

隔离性(Isolation):多个用户的并发事务访问同一个数据库时,一个用户的事务不应该被其他用户的事务干扰,多个并发事务之间要相互隔离。

持久性(Durability):持久性就是指如果事务一旦被提交,数据库中数据的改变就是永久性的。

2. 事务的隔离级别

①Read uncommitted/RU(读未提交):一个事务可以读取到另一个事务尚未提交的数据修改。

存在脏读问题、不可重复读问题、幻读问题

②Read committed/RC:(读已提交):每次读取数据时都能看到其他事务已提交的最新数据。oracle默认

存在不可重复读问题、幻读问题

在读已提交级别中,一个事务中每次查询数据时,都会创建一个新的ReadView,然后读取最近已提交的事务数据,因此就会造成不可重复读的问题。

③Repeatable read/RR:(可重复读):事务开始后,所有的读操作都看到的是事务开始时的数据快照。即事务在其开始时就创建一个快照(或视图),确保在整个事务期间,所有读操作都只能看到这个快照中的数据。mysql默认:存在幻读问题

写操作加排他锁,对读操作依旧采用MVCC机制,但RR级别中,一个事务中只有首次select会生成ReadView快照。

④Serializable:(序列化/串行化):并发执行的多个事务之间,数据库系统能够以某种方式序列化(或顺序化)这些事务的执行,从而避免可能导致数据不一致性的情况发生。

存在 不存在问题

越靠后并发控制度越高,也就是在多线程并发操作的情况下,出现问题的几率越小,但对应的也性能越差,MySQL的事务隔离级别,默认为第三级别:Repeatable read可重复读。
 

SELECT @@transaction_isolation;

set transaction isolation level read uncommitted;

begin;

commit;

rollback;

    savepoint point_name:添加一个事务回滚点

    rollback to point_name:回滚到指定的事务回滚点

2.1 数据库的脏读问题

脏读:是指一个事务读到了其他事务还未提交的数据,也就是当前事务读到的数据,由于还未提交,因此有可能会回滚,如下:

2.2 数据库不可重复读问题

不可重复读:是指在一个事务中,多次读取同一数据,先后读取到的数据不一致。

在一个事务中,对同一数据的多次读取结果不一致,这是由于其他事务在第一次读取之后对该数据进行了更新。如下:

假设有一张账户表(accounts):

账户ID余额
11000
 

2.3 数据库幻读问题

幻读:在一个事务中,对同一范围的查询结果不一致,这是由于其他事务在第一次查询之后在该范围内插入了新记录或删除了原有记录。

幻读问题:指同一个事务内多次查询返回的结果集不一样。比如同一个事务A,在第一次查询表的数据行数时,发现表中有n条行记录,但是第二次以同等条件查询时,却发现有n+1条记录,这就好像产生了幻觉。

假设有一张订单表(orders):

订单ID金额
1100
2200

幻读问题,发生幻读问题的原因是在于:另外一个事务在第一个事务要处理的目标数据范围之内新增了数据,然后先于第一个事务提交造成的问题。

2.4 数据库脏写问题

脏写的问题,也就是多个事务一起操作同一条数据,例如两个事务同时向表中添加一条ID=88的数据,此时就会造成数据覆盖,或者主键冲突的问题,这个问题也被称之为更新丢失问题

3.Mysql的锁

3.1 以锁粒度的维度划分

①表锁:

全局锁:加上全局锁之后,整个数据库只能允许读,不允许做任何写操作。

自增锁 / AUTO-INC锁:这个是为了提升自增ID的并发插入性能而设计的。

②行锁:

记录锁 / Record:也就是行锁,一条记录和一行数据是同一个意思。

间隙锁 / GapInnoDB中解决幻读问题的一种锁机制。

3.2 以互斥性的维度划分:

共享锁 / S锁:不同事务之间不会相互排斥、可以同时获取的锁。

排他锁 / X锁:不同事务之间会相互排斥、同时只能允许一个事务获取的锁。

3.3 以操作类型的维度划分:

读锁:允许多个事务同时读取同一行数据,而不会相互阻塞。获取共享锁的事务只能读取数据,不能修改数据。

写锁:执行插入、删除、修改、DDL语句时使用的锁。获取排它锁的事务可以读取和修改数据,但会阻塞其他事务获取任何类型的锁(包括共享锁和排它锁)。

3.4 以加锁方式的维度划分:

显示锁:编写SQL语句时,手动指定加锁的粒度。

隐式锁:执行SQL语句时,根据隔离级别自动为SQL操作加锁。

3.5 以思想的维度划分:

乐观锁:每次执行前认为自己会成功,因此先尝试执行,失败时再获取锁。

悲观锁:每次执行前都认为自己无法成功,因此会先获取锁,然后再执行。

总归说来说去其实就共享锁、排他锁两种,只是加的方式不同,加的地方不同,因此就演化出了这么多锁的称呼。

4. 多版本并发控制

4.1回滚日志(Undolog)

Undo Log:数据库事务开始之前,会将要修改的记录放到Undo日志里,当事务回滚时或者数据库崩溃时,可以利用UndoLog撤销未提交事务对数据库产生的影响。

Undo Log是事务原子性的保证。在事务中更新数据的前置操作其实是要先写入一个Undo Log

Undo Log日志里面不仅存放着数据更新前的记录,还记录着RowID事务ID回滚指针

那么如果当一个事务提交时,Undo的旧记录会不会立马被删除呢?因为事务都提交了,不需要再回滚改动过的数据,似乎用不上Undo旧记录了,对吗?确实如此,但不会立马删除Undo记录,对于旧记录的删除工作,InnoDB中会有专门的purger线程负责,purger线程内部会维护一个ReadView,它会以此作为判断依据,来决定何时移除Undo记录。

4.2 重做日志(redolog)

当一条写SQL执行时,不会直接去往磁盘中的xx.ibdata文件写数据,而是会写在undo_log_buffer缓冲区中,因为工作线程直接去写磁盘太影响效率了,写进缓冲区后会由后台线程去刷写磁盘。

Redo-log日志到磁盘,后台线程再根据Redo-log日志把数据落盘,这个动作似乎看起来有些多余对吧?但实际上这样做好处很大:

  • ①日志比数据先落入磁盘,因此就算MySQL崩溃也可以通过日志恢复数据。

  • ②写日志时是以追加形式写到末尾,而写数据时则是计算数据位置,随机插入。

4.3 MVCC

MySQL提供的锁机制确实能解决并发事务带来的一系列问题,但由于加锁后会让一部分事务串行化,而MySQL本身就是基于磁盘实现的,性能无法跟内存型数据库娉美,因此并发事务串行化会使其效率更低。MVCC通过保存数据的历史版本。可以通过比较版本号决定数据是否显示出来。读取数据的时候不需要加锁可以保证事务的隔离效果。

1.事务版本号

每开启一个日志,都会从数据库中获得一个事务ID(也称为事务版本号),这个事务 ID 是自增的,通过 ID 大小,可以判断事务的时间顺序。

2.隐藏字段

隐藏主键 - ROW_ID,最近更新的事务ID - TRX_ID,回滚指针 - ROLL_PTR

4.4 ReadView读视图

ReadView是“快照读”SQL执行时MVCC提取数据的依据。

快照读:就是最普通的Select查询SQL语句

当前读:指代执行下列语句时进行数据读取的方式

Insert、Update、Delete、 Select...for update、 Select...lock in share mode

Read committed和Repeatable read隔离级别的事务来说,都必须保证读到已经提交的事务修改过的记录。也就是说假如另一个事务已经修改了记录但是尚未提交,则不能直接读取最新版本的记录。

Read committed在每一次进行普通select操作前都会生成一个readview;Repeatable read只在第一次进行普通select操作前生成一个readview,之后的查询操作都重复使用这个readview。【特例:当两次快照读之间存在当前读,ReadView会重新生成,导致产生幻读】

如果一个事务要查询行记录,需要读取哪个版本的行记录呢? Read View 就是来解决这个问题的。Read View 可以帮助我们解决可见性问题。 Read View 保存了当前事务开启时所有活跃的事务列表。换个角度,可以理解为: Read View 保存了不应该让这个事务看到的其他事务 ID 列表。

例如:如果T2事务要查询一条行数据,此时这条行数据正在被T1事务写,那也就代表着这条数据可能存在多个旧版本数据,T2事务在查询时,应该读这条数据的哪个版本呢?此时就需要用到ReadView,用它来做多版本的并发控制,根据查询的时机来选择一个当前事务可见的旧版本数据读取。

可见性算法:

1.判断 当前事务id等于creator_trx_id(4)吗?成立说明数据就是自己这个事务改的,可以访问

2.判断 trx_id < min_trx_id(2)?成立说明数据已经提交了,可以访问

3.判断 trx_id > max_trx_id(5)?成立说明该事务是在ReadView生成以后才开启,不允许访问

4.判断 min_trx_id(2) <= trx_id <= max_trx_id(5),成立在m_ids数据中对比,不存在数据的则代表数据是已提交的,可以访问。

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

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

相关文章

树的概念与二叉树的实现

目录 一. 树的概念 二. 访问树的方法 1. 左孩子右兄弟法 2. 双亲表示法 3. 顺序表存孩子的指针&#xff08;孩子表示法&#xff09; 三. 二叉树 1. 二叉树的定义 2. 特殊二叉树 3. 二叉树的性质 4. 存储方式 四. 二叉树的前中后序遍历 1. 前序遍历 2. 中序遍历 3. …

C 语言中如何实现图结构?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&…

基于docker-compose部署zabbix7.0

1.安装docker和docker-compose 已有可跳过&#xff0c;没有参照我的docker一件安装脚本连接放在下方 一键安装dockerv24.0.6以及docker-compose可离线_docker 24对应docker-compose-CSDN博客 2.运行zabbix-server 1.创建zabbix工作目录 mkdir /zabbix 2.编写docker-compos…

【人工智能】Transformers之Pipeline(一):音频分类(audio-classification)

​​​​​​​ 目录 一、引言 二、音频分类&#xff08;audio-classification&#xff09; 2.1 概述 2.2 技术原理 2.2.1 Wav2vec 2.0模型 2.2.1 HuBERT模型 2.3 pipeline参数 2.3.1 pipeline对象实例化参数 2.3.2 pipeline对象使用参数 2.4 pipeline实战 2.4.1 …

【python】Python中常见的KeyError报错分析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

ESP32FreeRTOS开发笔记:1.双核并行

ESP32 的 Arduino 框架内部集成了 FreeRTOS&#xff0c;允许开发者利用其多任务处理功能。在代码中&#xff0c;xTaskCreatePinnedToCore 函数是 FreeRTOS 提供的 API&#xff0c;用于创建任务并指定任务在哪个核心上运行。 FreeRTOS 是一个流行的实时操作系统内核&#xff0c;…

信息打点web篇--语言开发框架,组件识别

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本章节主要整理 识别语言开发框的打点内容 框架简介 高效理解:把用于做某些事的代码封装起来&#xff0c;使用者无需自己写代码直接一个函数就能完成本该很多行才能完成的功能。 例子:我们要写网站&#xff0c;…

Open3D 点云Kmeans聚类算法

目录 一、概述 1.1算法介绍 1.2实现步骤 二、代码实现 三、实现效果 3.1原始点云 3.2聚类后点云 前期试读&#xff0c;后续会将博客加入该专栏&#xff0c;欢迎订阅Open3D与点云深度学习的应用_白葵新的博客-CSDN博客 一、概述 1.1算法介绍 聚类是一种将数据集分组的方…

Qml 图片和加载器操作

学习目标&#xff1a;Qml 图片和加载器编程 学习前置 Qt Qml编程 基础部分 认识qml-CSDN博客 实现效果 对图片的基本操作 加载器 核心代码 加载器 思路&#xff1a; 创建一个加载器 默认是几个圆点&#xff0c;我们重写加载器元素&#xff08;contentItem&#xff09;&…

文献阅读:高效和稳健的 π-FISH rainbow 用于多种生物分子的多重原位检测

文献介绍 文献题目&#xff1a; Highly efficient and robust π-FISH rainbow for multiplexed in situ detection of diverse biomolecules 研究团队&#xff1a; 曹罡&#xff08;华中农业大学&#xff09;、戴金霞&#xff08;华中农业大学&#xff09; 发表时间&#xff…

RSA算法(C++)

RSA加解密过程 RSA为非对称加密算法&#xff0c;由一对公钥和一对私钥构成&#xff0c;私钥加密公钥解密&#xff0c;公钥加密私钥解密 如下图,D为私密的&#xff0c;假设传输英文字母&#xff0c;我们给英文字母编号A1,B2,C3… RSA加解密过程 两对密钥产生方法如下 C Op…

网络通信基本知识

网络通信 什么是网络通信&#xff1f; 通信网络是指将各个孤立的设备进行物理连接&#xff0c;实现人与人&#xff0c;人与计算机&#xff0c;计算机与计算机之间进行信息交换的链路&#xff0c;从而达到资源共享和通信的目的。 什么是网络协议&#xff1f; 网络协议是计算机…

Python函数 之 参数

1.参数的简单介绍 参数 形式参数(形参)&#xff1a;在函数定义的时候,在括号中写⼊变量,这个变量就称为是函数的参数。实际参数(实参)&#xff1a;在函数调⽤的时候,可以给定义时候的形参传递具体的数据值,供其使⽤。注&#xff1a; 在函数调⽤的时候&#xff0c;会将函数的实…

wps 将列的内容转换为一个单元格内容,并以逗号分隔

wps 将列的内容转换为一个单元格内容&#xff0c;并以逗号分隔 1.首先在一个空白单元格输入 2.输入函数TEXTJOIN 这个函数有三个参数&#xff0c;第一个&#xff1a;以什么分隔符分隔&#xff0c;第二个&#xff1a;是否忽略空白格&#xff0c;true:忽略 false:不忽略 第三个&…

怎么使用代理IP?如何检测代理IP是否有效?

代理IP是一种网络代理技术&#xff0c;它是通过中间服务器来转发网络请求的IP地址。当我们使用代理IP时&#xff0c;我们的真实IP地址会被隐藏起来&#xff0c;而代理服务器的IP地址会被用作我们的身份标识。使用代理IP的步骤如下&#xff1a; 1.选择合适的代理服务器 考虑服务…

【微信小程序知识点】转发功能的实现

转发功能&#xff0c;主要帮助用户更流畅地与好友分享内容与服务。 想实现转发功能&#xff0c;有两种方式&#xff1a; 1.页面js文件必须声明onShareAppMessage事件监听函数&#xff0c;并自定义转发内容。只有定义了此事件处理函数&#xff0c;右上角菜单才会显示“转发”按…

WebStorm 使用 ESLint 自动格式化代码

WebStorm 不能像 VSCode 那样在保存的时候自动 Fix-ESLint&#xff0c;不能自动格式化代码&#xff0c;需要安装一个插件 安装 ESLint 插件 进入设置快捷键 win&#xff1a;CtrlAltS mac: command, 找到 Plugins&#xff0c;搜索eslint 在这里插入图片描述 安装后配置一下 …

【通信协议-RTCM】MSM语句(1) - 多信号GNSS观测数据消息格式

注释&#xff1a; RTCM响应消息1020为GLONASS星历信息&#xff0c;暂不介绍&#xff0c;前公司暂未研发RTCM消息类型版本的DR/RTK模块&#xff0c;DR/RTK模块仅NMEA消息类型使用 注释&#xff1a; 公司使用的多信号语句类型为MSM4&MSM7&#xff0c;也应该是运用最广泛的语句…

从新手到进阶:高效设计 Tableau 可视化的 5 种技巧 | 数据可视化分析

让我们一起跟着大神学习五个超实用的技巧&#xff0c;加速你的可视化分析之旅&#xff01; 在日常分析中&#xff0c;人人都想实现可视化最佳实践。然而&#xff0c;对于很多初学者来说&#xff0c;在还未熟练掌握 Tableau 的情况下&#xff0c;这种愿望貌似不太符合实际。 为…

【想心静?】红尘中修炼的功夫,才是真正的功夫

刘君亮想要去山中静坐&#xff0c;先生说&#xff1a; 你若是以厌弃身外事物的心去静中寻求天理&#xff0c;反而只会养出骄傲怠惰的习气。你若能不厌弃身外事物&#xff0c;然后再到静处涵养天理&#xff0c;却是好的。 去一个安静的地方&#xff0c;去沉静一下自己的内心也…