什么是事务?并发事务引发的问题?什么是MVCC?

news/2025/2/22 16:40:34

文章目录

  • 什么是事务?并发事务引发的问题?什么是MVCC?
      • 1.事务的四大特性
      • 2.并发事务下产生的问题:脏读、不可重复读、幻读
      • 3.如何应对并发事务引发的问题?
      • 4.什么是MVCC?
      • 5.可见性规则?
      • 参考资料

什么是事务?并发事务引发的问题?什么是MVCC?

1.事务的四大特性

  • 原子性是指事务中的所有操作要么全部执行成功,要么全部执行失败。
  • 一致性是指在事务执行前后,数据库的状态必须一致。
  • 隔离性是指数据库允许多个并发事务对同一个数据进行读写和修改的能力。
  • 持久性是指事务完成后对数据的修改是永久的。

2.并发事务下产生的问题:脏读、不可重复读、幻读

脏读就是指在事务A中已经修改过的数据被事务B读取了,但是这个事务A回滚了,那么事务B就是脏读了。

不可重复读是指事务A多次读取同一个数据,但是其中有一次被事务B修改了,那么就会造成前后不一致,这就是不可重复读。

幻读是指事务A多次查询数据数量,但是在其中某一次可能因为事务B的增删操作,发现不一致时,就是幻读。

按我理解就是说,不可重复读注重的是这个数据是否更新了,而幻读注重的时候是否进行了增删操作导致数据量变了。

3.如何应对并发事务引发的问题?

数据库为我们提供了四大隔离级别:读未提交、读提交、可重复读、串行化。

  • 读未提交:事务可以读取其他事务未提交的数据,如果未提交的事务回滚,那么这些数据就是无效的。
  • 读提交:事务只能读取其他事务提交的数据。但是在事务A中多次读取同一数据,若其他事务已经提交了对这个数据的修改,就会造成不可重复读问题。
  • 可重复读隔离级别:在一个事物执行过程中看到的数据都是这个事务启动时的数据快照,就算是修改了这个数据并提交的事务也不会影响这个数据快照。但是若进行insert和delete操作就会发生幻读现象。
  • 串行化:通过加锁机制,确保事务串行执行,避免所有并发问题。

那么这些隔离级别是怎么实现的呢?

对于读未提交隔离级别,什么问题也没有解决,所以直接读取最新的数据即可。

对于读提交和可重复读隔离级别,都是通过MVCC实现的,只是创建的read view时机不同。

对于串行化,通过加读写锁的方式避免并行访问。

4.什么是MVCC?

MVCC是MySQL在创建事务时,读提交和可重复读隔离级别使用的核心控制机制。

MVCC是通过undo日志版本链和read view实现的,每一个事务在创建的时候都会生成一个read view。

在这里插入图片描述

m_ids:当前活跃事务的 ID 列表。

min_trx_idm_ids 中的最小事务 ID。

max_trx_id:下一个即将分配的事务 ID。

creator_trx_id:创建该 Read View 的事务 ID。

在这里插入图片描述

read view有四个字段+行数据中隐藏的两个字段实现了MVCC。行数据中的两个隐藏列实现了undo log版本链,trx_id记录正字啊操作这个行数据的事务,roll_pointer记录上一个历史版本的数据用来回滚操作。

MVCC就是通过trx_id、回滚指针和read view共同实现事务的可见性规则的。

在读提交和可重复读隔离级别下,需要通过MVCC来实现。

读提交是在事务执行过程中,每进行select操作时都会创建一个read view,所以每次select都能看到其他事务最近提交的数据。可重复读是在事务开始执行时创建一个read view并且在之后执行过程中都复用这个read view,那么在查询数据的时候都是事务开始之前的数据。

那么MVCC就是在这两个隔离级别下所使用的核心机制,避免了锁的使用(写操作还是需要加锁的),因为锁的效率更低。

MVCC的实现流程:每个事务都会创建一个read view,并且有唯一一个creator_trx_id,如果这个事务中操作了某些行数据,那么就会将这个creator_trx_id记录到行数据的trx_id中,并且会让行数据的回滚指针指向历史版本,然后这个read view就会统计当前系统中活跃的事务id到m_ids列表中,min_trx_id记录最小的值,max_trx_id记录要创建的事务的下一个id,如果某个事务需要回滚那么就会通过这个creator_trx_id去查找对应的最新的trx_id的行数据,然后遍历回滚指针恢复到最初的数据。

如何去判断这个read view是怎么进行可见性规则的?m_ids就是活跃事务列表,仅存放所有还在活跃的事务。 这个m_ids分为三部分,已经提交的事务,正在活跃的事务区间,但是这个区间内部也有已经提交的事务因为并发,以及待未创建的事务id,如果在第一部分是可以读取的,在第二部分要去进行判断(错误描述)。

那我是不是可以理解为 这个m_ids列表存放的事务id,其实系统中的所有read view的m_ids都是一样的呢?

不是的,m_ids中存放的创建当前read view是系统中活跃的事务id(自身不计入)。

综上,MVCC就是多版本并发控制,通过记录历史版本数据,解决了读写冲突问题,避免了查询数据时加读锁,提高了事务的并发性能。事务在启动时,会创建read view记录当前未提交的事务,通过与历史版本数据的事务id根据可见性规则判断,当前记录是否可见,否则就继续跟进undo log版本链去查早最近的可见数据。

5.可见性规则?

可见性规则是由read view实现的,read view中有四个字段:creator_trx_id、min_trx_id、max_trx_id、m_ids。

如果记录的事务id小于min_trx_id,那么就是可见的。

如果记录的事务id大于等于max_trx_id,就是不可见的。

如果记录的事务id在min_trx_id和max_trx_id之间,还需要判断这个id是否存在于m_ids中,若存在就是未提交,是不可见的,否则就是可见的。

参考资料

1、https://xiaolincoding.com/mysql/transaction/mvcc.html#%E4%BA%8B%E5%8A%A1%E7%9A%84%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB%E6%9C%89%E5%93%AA%E4%BA%9B


http://www.niftyadmin.cn/n/5862530.html

相关文章

两相四线步进电机的步距角为什么是1.8度

机缘 在CSDN查了好多文章,发现都是用公式来解释1.8的步距角(Q=360/MZ),因为转子是50齿,4拍一个循环,所以θ360度/(50x4)1.8度。估计第一次接触步进电机的什么…

SPRING10_SPRING的生命周期流程图

经过前面使用三大后置处理器BeanPostProcessor、BeanFactoryPostProcessor、InitializingBean对创建Bean流程中的干扰,梳理出SPRING的生命周期流程图如下

科普mfc100.dll丢失怎么办?有没有简单的方法修复mfc100.dll文件

当电脑频繁弹窗提示“mfc100.dll丢失”或应用程序突然闪退时,这个看似普通的系统文件已成为影响用户体验的核心痛点。作为微软基础类库(MFC)的核心组件,mfc100.dll直接关联着Visual Studio 2010开发的大量软件运行命脉。从工业设计…

VUE3+TS+element-plus项目从0开始入门 - 创建项目、认识基本结构

文章目录 写在前面1、创建vue3项目npm create vuelatestnpm i 2、项目结构.vscodevue3结构a、项目树结构b、package.jsonc、tsconfig.jsond、index.htmld、srce、main.tsf、App.vue 写在前面 开前请自行下载vs code、node.js, 在vs code里面安装Vue - Official插件。本文使用的…

Rpc导读

手写Rpc框架 - 导读 git仓库-all-rpc GTIEE:https://gitee.com/quercus-sp204/all-rpc 【参考源码 yrpc】 1. Rpc概念 RPC 即远程过程调用(Remote Procedure Call) ,就是通过网络从远程计算机程序上请求服务。 本地调用抽象&…

番茄工作法html实现

对比了deepseek-r1-online和本地部署的14b的版本,输出的输出的html页面。 在线满血版的功能比较强大,可以一次完成所有要求。14b版本的功能有一些欠缺,但是基本功能也是写了出来了。 input write a html named Pomodoro-clock which “hel…

机器人路径规划 | 基于极光PLO优化算法的机器人三维路径规划Matlab代码

基于极光PLO优化算法的机器人三维路径规划 完整代码私信回复基于极光PLO优化算法的机器人三维路径规划Matlab代码 一、引言 1.1、研究背景与意义 机器人路径规划是机器人技术中的一个核心问题,它涉及到在复杂环境中寻找一条从起点到终点的最优或次优路径。这一问…

国产超强开源大语言模型 DeepSeek-R1-70B 一键部署教程

DeepSeek-R1-Distill-Llama-70B 是深度求索 (DeepSeek) 公司于 2025 年推出的开源大语言模型,参数规模高达 700 亿。它是基于 Llama3.3-70B-Instruct 进行训练的,采用强化学习和蒸馏技术提升推理表现,不仅继承了 Llama 系列模型的优势&#x…