掌握 MySQL 事务:ACID、隔离级别详解

一、前言

  • 事务是关系型数据库中的重要概念,用于保证一组数据库操作作为一个单独的工作单元来执行。无论是银行转账、订单处理还是复杂的数据修改,事务都能保证操作的一致性和完整性。

  • 本文将带您从基础概念到高级技巧,全面了解 MySQL 事务的工作原理、使用方法和优化策略。

二、事务基础

什么是事务?

  • 定义:事务是一组操作的集合,这些操作要么全部执行,要么全部不执行。

  • 事务的目的:确保数据库操作的一致性、完整性、隔离性和持久性(ACID 属性)。

事务的 ACID 属性

原子性 (Atomicity)

事务是不可分割的最小操作单位,要么全部执行,要么全部不执行。主要是commit、rollback、autocommit来保证原子性。

一致性 (Consistency)

所谓一致性,就是保证数据的一致,也就是保证数据不要丢失,不会因为突然的断电等导致数据与想要的数据不一致。主要体现在:

  1. 双写 保证内存跟磁盘之间同步的数据安全

  2. 基于RedoLog的数据恢复

隔离性 (Isolation)一个事务的执行不应受其他事务的干扰。主要体现在:

  1. 事务的隔离级别

  2. InnoDb的锁机制

持久性 (Durability)

一旦事务提交,对数据库的修改是永久性的,即使系统崩溃也不会丢失。InnoDB去保证持久性主要体现在:

  1. 双写 保证内存同步到磁盘,就算page损坏的情况下也能恢复

  2. RedoLog的同步机制

  3. binlog的同步机制

事务的开启提交回滚

START TRANSACTION -- 开始一个事务。
COMMIT -- 提交事务,保存所有的更改。
ROLLBACK -- 回滚事务,撤销事务中的所有更改。

自动提交

大家想一下我们平时写sql为什么没加上面的那些事务语句呢?这是因为我们Mysql里面,Mysql默认以自动提交模式运行的,简单来讲,就是每个语句,当没有START TRANSACTION开启事务的时候,每个语句都默认START TRANSACTION、commit包围,并且不能用ROLLBACK来回滚。但是如果执行期间发生了错误,则进行回滚。

查询是否开启自动提交

show SESSION VARIABLES like 'autocommit'; -- 查询(会话)是否开启自动提交
show GLOBAL VARIABLES like 'autocommit'; -- 查询(全局)自动开启提交

三、MySQL 中事务

大家想想,如果没有事务,数据的查询会有哪些问题呢?

数据一致性问题

脏读: 能读取到其他线程还没有提交的数据;但是这些数据可能是会回滚的。

不可重复读: 在开启事务之后,读取到其他事务进行修改或者删除提交的的数据。

幻读: 在开启事务之后,读到了其他事务新添加的新数据。

非锁定一致性读取(MVCC,快照读)

既然有上面那些问题,那么我们看看mysql是怎么解决这些问题的,首先我们需要先来了解几个知识点。

事务的隔离级别

  1. READ UNCOMMITTED:最低隔离级别,允许事务读取未提交的数据(脏读)。

  2. READ COMMITTED:保证事务只能读取已提交的数据,避免脏读,但可能会发生不可重复读。

  3. REPEATABLE READ:事务中的查询在整个事务期间保持一致,避免了不可重复读,但可能会有幻读。(innodb默认事务隔离级别)

  4. SERIALIZABLE:最高隔离级别,强制事务串行执行,避免所有并发问题,但性能开销大。

ReadView结构

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

m_up_limit_id:所有存活的(没有提交的)事务ID中最小值。

m_creator_trx_id:创建这个readView的事务ID。

m_ids:创建readView时,所有存活的事务ID列表。

行隐藏字段

DB_TRX_ID:更新这行数据的事务ID。

DB_ROLL_PTR :回滚指针,被改动前的undolog日志指针。

判断是否可见逻辑

有了上面几个知识点,我们来看看ReadView怎么跟我的行数据的DB_TRX_ID来配合 做到解决我的不可

重复读或者幻读问题呢?(这里就不画图了,画图太复杂了,大家多理解下下面的规则)

  1. 如果数据的DB_TRX_ID < m_up_limit_id, 都小于存活的事务ID了,那么肯定不存活了,说明在创建ReadView的时候已经提交了,可见。意思就是,A事务已经提交了,B事务才开始查询,那么肯定可以查询到最新的数据。

  2. 如果数据的DB_TRX_ID >=m_low_limit_id, 大于等于我即将分配的事务ID, 那么表明修改这条数据的事务是在创建了ReadView之后开启的,不可见。

  3. 如果 m_up_limit_id<= DB_TRX_ID< m_low_limit_id, 表明修改这条数据的事务在第一次快照之前就创建好了,但是不确定提没提交,判断有没有提交,直接可以根据活跃的事务列表 m_ids判断

DB_TRX_ID如果在m_ids中,表面在创建ReadView之时还没提交,不可见

DB_TRX_ID如果不在m_ids,表面在创建ReadView之时已经提交,可见

UndoLog日志查询以往版本的数据

所谓UndoLog,也就是回滚日志,简单点,当我需要回滚的时候,能找到之前相关的数据。比如,我们rollback或者异常中断的时候,能找到改动之前的数据进行恢复。当然,我们在mvcc中也需要用到undolog来找到以往的数据来解决不可重复读跟幻读问题。

那么undolog到底怎么记录的,我们来看下面这个图:

四、事务的并发控制

锁机制

**行级锁 (Row-level Lock)**:InnoDB 默认使用行级锁,它允许更多的并发操作,减少锁冲突。

**表级锁 (Table-level Lock)**:MyISAM 使用表级锁,可能导致较大的锁竞争。

锁的类型

记录锁(Record Locks)

记录锁,顾名思义,是锁在索引记录上的锁,索引扫描某些数据的时候,在这些索引数据上加锁。

SELECT * FROM user where id=1 FOR UPDATE; -- 索引扫描到id=1的数据,那么会锁id=1的数据,其他事务不能进行操作

间隙锁(Gap Locks)

间隙锁是对索引记录之间的间隙的锁。所谓间隙,就是索引数据之间的间隙,那么间隙锁,就是锁住数据之间的间隙,不允许间隙之内添加数据。看看下面的例子:

SELECT * FROM user where id > 1 AND id < 5 FOR UPDATE; -- 这里因为没有命中索引,所以索引1 和 5 之间不能添加id为2,3,4的数据

临键锁(Next-Key Locks)

临键锁是索引记录上的记录锁和索引记录之前的间隙上的间隙锁的组合。就是我扫描的数据,既包含索引中存在的数据,又是扫描的一个区间。看看下面的例子:

SELECT * FROM user where id > 4 AND id < 8 FOR UPDATE; -- 这里命中了索引4,所以索引1 和 5 之间和5和9之间不能添加id为2,3,4,6,7,8的数据,并且id=4这条数据不能修改

五、总结

  • 事务是 MySQL 数据库中重要的概念,它保证了操作的原子性、一致性、隔离性和持久性(ACID 属性)。

  • MySQL 提供了丰富的事务控制功能,包括事务隔离级别、锁机制、死锁检测等。


最后。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nacos 3.0 Alpha 发布,在安全、泛用、云原生更进一步

自 2021 年发布以来&#xff0c;Nacos 2.0 在社区的支持下已走过近三年&#xff0c;期间取得了诸多成就。在高性能与易扩展性方面&#xff0c;Nacos 2.0 取得了显著进展&#xff0c;同时在易用性和安全性上也不断提升。想了解更多详细信息&#xff0c;欢迎阅读我们之前发布的回…

23.DDD与微服务

学习视频来源&#xff1a;DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 DDD与微服务的关系1. DDD可以用微服务实现&#xff0c;也可以不用微服务实现2. DDD是微服务拆分的必须参考项之一3. 微服务架构…

拍频实例 - 一组恒力矩电流采样数据

这是一组功率电机的感应电流波形。加载了重载恒力矩设备。你能看到什么&#xff1f; 首先&#xff0c;时间轴的坐标是对的&#xff0c;9.9~10.0秒&#xff0c;单位是秒&#xff0c;100ms有5个波形&#xff0c;所以是20ms一个波形。这是50Hz的信号。频差就体现为幅度的周期起伏…

用前端html如何实现2024烟花效果

用HTML、CSS和JavaScript编写的网页&#xff0c;主要用于展示“2024新年快乐&#xff01;”的文字形式烟花效果。下面是对代码主要部分的分析&#xff1a; HTML结构 包含三个<canvas>元素&#xff0c;用于绘制动画。引入百度统计的脚本。 CSS样式 设置body的背景为黑…

【组件介绍】FITKPlotWindow

一、组件简介 二维图表组件FITKPlotWindow基于Qwt开发&#xff0c;是用于直观二维数据的组件。目前的二维图表组件支持四种类型的图表&#xff0c;分别为标准直角坐标图、柱状图、频谱图和极坐标图。该组件的数据渲染效果示例如下&#xff1a; 二、主要接口 组件中针对不同的…

路由策略与策略路由

路由策略 常用有Router-Policy&#xff0c;Filter-Policy等 控制路由是否可达&#xff0c;通过修改路由条目相关参数影响流量的转发 基于控制平面&#xff0c;会影响路由表表项&#xff0c;但只能基于目地址进行策略判定&#xff0c;于路由协议相结合使用 Router-Policy …

软考:工作后再考的性价比分析

引言 在当今的就业市场中&#xff0c;软考&#xff08;软件设计师、系统分析师等资格考试&#xff09;是否值得在校学生花费时间和精力去准备&#xff1f;本文将从多个角度深入分析软考在不同阶段的性价比&#xff0c;帮助大家做出明智的选择。 一、软考的价值与局限性 1.1 …

批量导出工作簿中高清图片-Excel易用宝

我同事在工作簿中做了三个图表&#xff0c;现在需要将工作簿中的图标导出保存为高清图片&#xff0c;通过右键另存为保存的图片并非高清图片&#xff0c;其实要把Excel工作簿中的图表或图片对象导出为高清图片也很简单。 单击Excel易用宝 Plus&#xff0c;导出高清图片。 在导出…

mp4影像和m4a音频无损合成视频方法

第一步&#xff1a;复制高清视频地址 url 第二步:打开网址粘贴复制的视频url视频下载 第三步&#xff1a;下载-影像.mp4和-音频.m4a 第四步&#xff1a;合并视频&#xff1b; 使用ffmpeg进行无损合成&#xff08;如果没有安装ffmpeg请自行下载安装下载 FFmpeg (p2hp.com)&…

Docker-Dockerfile、registry

Dockerfile 一、概述 1、commit的局限 很容易制作简单的镜像&#xff0c;但碰到复杂的情况就十分不方便&#xff0c;例如碰到下面的情况&#xff1a; 需要设置默认的启动命令需要设置环境变量需要指定镜像开放某些特定的端口 2、Dockerfile是什么 Dockerfile是一种更强大的镜…

视频监控汇聚平台方案设计:Liveweb视频智能监管系统方案技术特点与应用

随着科技的发展&#xff0c;视频监控平台在各个领域的应用越来越广泛。然而&#xff0c;当前的视频监控平台仍存在一些问题&#xff0c;如视频质量不高、监控范围有限、智能化程度不够等。这些问题不仅影响了监控效果&#xff0c;也制约了视频监控平台的发展。 为了解决这些问…

多线程动态库里面调用静态库分配内存函数导致的崩溃cltp汇编指令导致

1、概述 有这样的一个场景,我有一个动态库myso.so里面有函数start_crash()&#xff0c;用到静态库的内存分配函数&#xff0c;其实静态库里面的static.a 里面就封装了一个函数叫system_malloc(),函数返回的是分配的内存地址&#xff0c;然后发现&#xff0c;我在测试demo里面创…

GoTrackIt应用指南:共享单车时空轨迹优化

本篇文章我们来基于GoTrackIt 包来研究一下里面的轨迹数据清洗功能&#xff0c;该包这部分功能是一个用于处理和分析GPS轨迹数据的工具&#xff0c;能够帮助用户进行诸如卡尔曼滤波平滑、轨迹简化&#xff1b;停留点删除、增密、降频、滑动窗口平滑的链式操作&#xff0c;并提供…

【kubernetes】k8s集群的简述与搭建

简述 Kubernetes&#xff08;简称 K8s&#xff09;是一个开源的容器编排平台&#xff0c;用于自动化部署、扩展和管理容器化应用程序 关键特性 自动化部署和回滚&#xff1a;Kubernetes 可以自动化地部署和回滚应用程序&#xff0c;确保应用程序始终处于预期的状态。服务发现…

华为USG系列防火墙 RESTCONF NAT配置 Python实现

目录 前言 文档下载 开启RESTCONF接口 Python 实现SNAT增删改查 查看nat映射列表 查看私网地址池 查看源地址池&#xff08;公网&#xff09; 查看nat映射规则 创建nat映射规则 创建私网地址池 创建源地址池 创建nat映射规则 修改NAT映射规则 删除NAT映射规则 …

token失效重新存储发起请求

import axios from axios import { MessageBox, Message } from element-ui import store from /store import Router from /router import { getCookie, setToken, setCookie } from ./auth// 因为后端环境区分v1 v2 剔除测试盛传的环境配置&#xff0c;并添加统一前缀 const …

HTML综合

一.HTML的初始结构 <!DOCTYPE html> <html lang"en"><head><!-- 设置文本字符 --><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><!-- 设置网页…

【合作原创】使用Termux搭建可以使用的生产力环境(六)

前言 在上一篇【合作原创】使用Termux搭建可以使用的生产力环境&#xff08;五&#xff09;-CSDN博客我们讲到了如何美化xfce4桌面&#xff0c;达到类似于Windows的效果&#xff0c;这一篇将继续在上一篇桌面的基础上给我们的系统装上必要的软件&#xff0c;让它做到真正可以使…

python3中幂怎么表示

首先导入math模块&#xff0c;然后调用pow()函数&#xff0c;即可实现幂运算&#xff0c;示例如下&#xff1a; import math math.pow(2&#xff0c;3) 结果如下&#xff1a; 8

AES笔记整理

文章目录 1. 简介2. 密钥加法层2. 字节代换层3. 行位移 - ShiftRows4. 列混淆 - MixColumn5. 其他5.1列混淆矩阵乘法运算5.2 AES密钥生成 6. 参考资料 以下内容为信息安全开发过程中&#xff0c;AES对称加密算法的笔记&#xff0c;大部分内容转载其他文章&#xff0c;若描述不清…