浅入浅出MySQL事务

什么是事务

事务是由数据库中一系列的访问和更新组成的逻辑执行单元。

事务的逻辑单元中可以是一条SQL语句,也可以是一段SQL逻辑,这段逻辑要么全部执行成功,要么全部执行失败。

事务处理的基本原则是“原子性”、“一致性”、“隔离性”和“持久性”:

  • 原子性:事务中的所有操作必须全部成功,或者全部失败。如果一个操作失败,那么事务将回滚,数据库将不会被更改
  • 一致性:事务必须使数据库从一个一致状态转换到另一个一致状态。这意味着事务必须确保数据库中的数据始终处于正确的状态
  • 隔离性:事务的执行不会被其他事务的执行干扰。这意味着在一个事务执行期间,其他事务无法看到该事务正在执行的更改
  • 持久性:一旦事务提交,其更改将永久保存在数据库中。即使数据库发生故障,事务的更改也不会丢失

举个最常见的例子,你早上出去买早餐,支付宝扫码付款给早餐老板,这就是一个简单的转账过程,会包含两步:

  • 从你的支付宝账户扣款10元
  • 早餐老板的账户增加10元

这两步其中任何一部出现问题,都会导致整个账务出现问题:

  • 假如你的支付宝账户扣款10元失败,早餐老板的账户增加成功,那你就Happy了,相当于马云请你吃早餐了
  • 假如你的支付宝账户扣款10元成功,早餐老板的账户增加失败,那你就悲剧了,早餐老板不会放过你,会让你重新付款,相当于你请马云吃早餐了

事务就是用来保证一系列操作的原子性,上述两步操作,要么全部执行成功,要么全部执行失败。

实现

数据库为了保证事务的原子性和持久性,引入了redo log和undo log。

redo log

redo log是重做日志,通常是物理日志,记录的是物理数据页的修改,它用来恢复提交后的物理数据页。

在这里插入图片描述

如上图所示,redo log分为两部分:

  • 内存中的redo log Buffer是日志缓冲区,这部分数据是容易丢失的
  • 磁盘上的redo log file是日志文件,这部分数据已经持久化到磁盘,不容易丢失

SQL操作数据库之前,会先记录重做日志,为了保证效率会先写到日志缓冲区中(redo log Buffer),再通过缓冲区写到磁盘文件中进行持久化,既然有缓冲区说明数据不是实时写到redo log file中的,那么假如redo log写到缓冲区后,此时服务器断电了,那redo log岂不是会丢失?

在MySQL中可以自已控制log buffer刷新到log file中的频率,通过innodb_flush_log_at_trx_commit参数可以设置事务提交时log buffer如何保存到log file中,innodb_flush_log_at_trx_commit参数有3个值(0、1、2),表示三种不同的方式:

  • 为1表示事务每次提交都会将log buffer写入到os buffer,并调用操作系统的fsync()方法将日志写入log file,这种方式的好处是就算MySQL崩溃也不会丢数据,redo log file保存了所有已提交事务的日志,MySQL重新启动后会通过redo log file进行恢复。但这种方式每次提交事务都会写入磁盘,IO性能较差
  • 为0表示事务提交时不会将log buffer写入到os buffer中,而是每秒写入os buffer然后调用fsync()方法将日志写入log file,这种方式在MySQL系统崩溃时会丢失大约1秒钟的数据
  • 为2表示事务每次提交仅将log buffer写入到os buffer中,然后每秒调用fsync()方法将日志写入log file,这种方式在MySQL崩溃时也会丢失大约1秒钟的数据

undo log

undo log是回滚日志,用来回滚行记录到某个版本,undo log一般是逻辑日志,根据行的数据变化进行记录。

undo log跟redo log一样也是在SQL操作数据之前记录的,也就是SQL操作先记录日志,再进行操作数据。

在这里插入图片描述

如上图所示,SQL操作之前会先记录redo log、undo log到日志缓冲区,日志缓冲区的数据会记录到os buffer中,再通过调用fsync()方法将日志记录到log file中。

undo log记录的是逻辑日志,可以简单的理解为:当insert一条记录时,undo log会记录一条对应的delete语句;当update一条语句时,undo log记录的是一条与之操作相反的语句。

当事务需要回滚时,可以从undo log中找到相应的内容进行回滚操作,回滚后数据恢复到操作之前的状态。

undo日志还有一个用途就是用来控制数据的多版本(MVCC)。

undo log是采用段(segment)的方式来记录的,每个undo操作在记录的时候占用一个undo log segment。

另外,undo log也会产生redo log,因为undo log也要实现持久性保护。

总结

MySQL中是如何实现事务提交和回滚的?

  • 为了保证数据的持久性,数据库在执行SQL操作数据之前会先记录redo log和undo log
  • redo log是重做日志,通常是物理日志,记录的是物理数据页的修改,它用来恢复提交后的物理数据页
  • undo log是回滚日志,用来回滚行记录到某个版本,undo log一般是逻辑日志,根据行的数据变化进行记录
  • redo/undo log都是写先写到日志缓冲区,再通过缓冲区写到磁盘日志文件中进行持久化保存
  • undo日志还有一个用途就是用来控制数据的多版本(MVCC)

简单理解就是:

  • redo log是用来恢复数据的,用于保障已提交事务的持久性
  • undo log是用来回滚事务的,用于保障未提交事务的原子性

实践

创建事务

在MySQL中,可以使用BEGIN语句开始一个事务,例如:

BEGIN;  
-- 这里添加事务处理语句,如INSERTUPDATEDELETECOMMIT;

事务操作

在事务中,可以使用以下操作方法来处理数据:

  • 插入:使用INSERT语句插入新记录
  • 更新:使用UPDATE语句修改现有记录
  • 删除:使用DELETE语句删除记录
  • 条件查询:使用SELECT语句查询符合条件的记录

例如,以下是一个插入、更新和删除操作的示例:

BEGIN;  
INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2');  
UPDATE table_name SET column1 = 'new_value' WHERE id = 1;  
DELETE FROM table_name WHERE id = 1;  
COMMIT;

事务管理

在MySQL中,可以使用以下语句来管理事务:

  • COMMIT:提交事务,将事务中的所有操作永久保存到数据库
  • ROLLBACK:回滚事务,撤销所有未提交的更改,并将数据库恢复到事务开始之前的状态
  • SAVEPOINT:在事务中设置保存点,以便在需要时回滚部分事务
  • SET TRANSACTION:设置事务的隔离级别、并发模式等属性

事务处理流程

MySQL事务处理流程一般包括以下步骤:

  • 开始事务
  • 执行一系列数据库操作
  • 评估事务是否成功,如果成功,则提交事务;否则,回滚事务

在MySQL中,可以使用COMMIT语句提交事务,或使用ROLLBACK语句回滚事务。例如:

BEGIN;  
-- 这里添加事务处理语句  
COMMIT; -- 提交事务  
ROLLBACK; -- 回滚事务

实战演练

下面通过一个实际的案例来说明如何使用MySQL事务处理来处理大量数据。假设我们有一个表格,用于记录学生的成绩信息,我们需要在一个事务中插入多个学生的成绩数据,以确保数据的一致性和完整性。

CREATE TABLE student_scores (  id INT AUTO_increment PRIMARY key,  student_id INT,  course_id INT,  score FLOAT  
);

现在,我们需要在同一个事务中插入多个学生的成绩数据。示例代码如下:

BEGIN; -- 开始事务  
INSERT INTO student_scores (student_id, course_id, score) VALUES (1, 1, 85);  
INSERT INTO student_scores (student_id, course_id, score) VALUES (2, 1, 90);  
INSERT INTO student_scores (student_id, course_id, score) VALUES (3, 1, 80);  
-- 这里添加更多插入语句或更新、删除语句  
COMMIT; -- 提交事务

如果插入过程中发生错误,所有插入的数据都将被回滚,以确保数据的一致性和完整性。

在MySQL中,可以使用以下语句来查看当前事务的状态:

SELECT * FROM INFORMATION_SCHEMA.INNODB_trx;

该语句将返回当前正在运行的所有事务的信息,包括事务的ID、状态、持有锁等等。

最佳实践

以下是一些MySQL事务处理的最佳实践:

  • 使用事务处理语句:BEGIN和COMMIT/ROLLBACK是MySQL事务处理的核心语句,必须使用它们来确保事务的一致性和完整性
  • 确保事务的原子性:事务处理应该是一个原子操作,要么全部执行成功,要么全部回滚。在事务中,如果发生错误或异常,应该立即执行ROLLBACK语句,以确保数据的一致性
  • 设置合适的隔离级别:在事务中,应该设置合适的隔离级别来确保数据的一致性和完整性。一般来说,较高的隔离级别可以提高数据的一致性,但也会影响性能
  • 使用锁:在事务中,应该使用锁来保护数据,避免并发访问导致的数据冲突和脏读等问题
  • 设计合适的数据结构:在事务中,应该确保数据结构的正确性和一致性,避免数据异常和数据丢失等问题
  • 分阶段提交:在大型事务中,应该将事务分为多个阶段,并逐个提交每个阶段,以避免长时间阻塞和死锁问题

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

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

相关文章

114.(cesium篇)cesium去掉时间轴并用按钮控制运动

地图之家总目录(订阅之前必须详细了解该博客) 地图之家:cesium+leaflet+echart+地图数据+地图工具等相关内容的介绍 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: cesium去掉时间轴并用按钮控制运动 下面献上完整代码,代码重要位…

《网络是怎样连接的》(二.2)

(6条消息) 《网络是怎样连接的》(二.1)_qq_38480311的博客-CSDN博客 本文主要取材于 《网络是怎样连接的》 第二章 2.5 2.6章节。 目录 简述: 本文的主要内容是 以太网的收发操作 和 UDP协议的收发操作。 IP与以太网的包收发操作 包是什…

Java反射(一)

目录 1.了解反射 2.Class类的三种实例化方法 3.反射机制与对象实例化 4.反射与单例设计模式 5.通过反射获取类结构的信息 1.了解反射 什么是反射,反射有什么作用 1.在Java中,反射是一种机制,允许程序在运行时动态地获取、使用和修改类的…

ChatGPT学python——制作自己的AI模型(一)初步了解

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★前端炫酷代码分享 ★ ★ uniapp-从构建到提升★ ★ 从0到英雄,vue成神之路★ ★ 解决算法,一个专栏就够了★ ★ 架…

大数据课程E1——Flume的概述

文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Ganglia的概念; ⚪ 了解Ganglia的拓扑结构和执行流程; ⚪ 掌握Ganglia的安装操作; 一、简介 1. 概述 1. Flume原本是由Cloude…

【华为HCIP | 高级网络工程师】刷题日记(11)

个人名片: 🐼作者简介:一名大二在校生,喜欢编程🎋 🐻‍❄️个人主页🥇:落798. 🐼个人WeChat:见文末 🕊️系列专栏:🖼️ 零…

数据结构和算法入门(时间/空间复杂度介绍--java版)

数据结构和算法入门(时间/空间复杂度介绍–java版) write in front 作者: 向大佬学习 专栏: 数据结构(java版) 作者简介:大二学生 希望能学习其同学和大佬的经验! 本篇博客简介&…

微信小程序页面传值为对象[Object Object]详解

微信小程序页面传值为对象[Object Object]详解 1、先将传递的对象转化为JSON字符串拼接到url上2、在接受对象页面进行转译3、打印结果 1、先将传递的对象转化为JSON字符串拼接到url上 // info为对象 let stationInfo JSON.stringify(info) uni.navigateTo({url: /pages/statio…

jenkins自定义邮件发送人姓名

jenkins发送邮件的时候发送人姓名默认的&#xff0c;如果要自定义发件人姓名&#xff0c;只需要修改如下信息即可&#xff1a; 系统管理-system-Jenkins Location下的系统管理员邮件地址 格式为&#xff1a;自定义姓名<邮件地址>

VMware虚拟机安装Linux教程(超详细)

一、安装 VMware 官方正版VMware下载&#xff08;16 pro&#xff09;&#xff1a;https://www.aliyundrive.com/drive/file/backup/64c9fa3c132e0d42c60d489c99f3f951ef112ad5 下载Linux系统镜像&#xff08;阿里云盘不限速&#xff09;&#xff1a;https://www.aliyundrive.c…

CCL 2023 电信网络诈骗案件分类评测-第一名方案

1 任务内容 1.1 任务背景 2022年12月1日起&#xff0c;新出台的《反电信网络诈骗犯罪法》正式施行&#xff0c;表明了我国治理当前电信网络诈骗乱象的决心。诈骗案件分类问题是打击电信网路诈骗犯罪过程中的关键一环&#xff0c;根据不同的诈骗方式、手法等将其分类&#xff…

tp-link端口映射设置教程及快解析内网穿透

通常情况下&#xff0c;我们希望互联网的其他用户访问到我们本地局域网内部的一台服务器、监控……等设备或应用&#xff0c;就要在本地路由器或防火墙的出接口/路由器WAN口 上做端口映射&#xff0c;将内部局域网某台计算机的私网IP&#xff0c;如&#xff1a;192.168.1.101 内…

手写一个锁其实也很easy

懵逼的状态&#xff1a; 面试中经常被问到&#xff0c;如何手写一个锁&#xff0c;很多时候一脸懵逼&#xff0c;不知所措&#xff0c;多少年前深有体会&#xff0c;然而回过头来细细分析&#xff0c;只需使用AtomicReference类 即可以轻松搞定。首先咱们先来了解一下Atomi…

数据截断、频谱泄漏与窗函数的选择

目录 数据截断、频谱泄漏与窗函数的选择 什么是频谱泄漏&#xff1f; 解决频谱泄漏问题的方法 主瓣和旁瓣 窗函数介绍 窗函数解决频谱泄漏问题的原理 窗函数的种类、特点和如何使用 1、矩形窗 2、三角窗 3、汉宁窗 4、海明窗 5、布莱克曼窗 6、巴特窗&#xff1a;…

opencv 31-图像平滑处理-方框滤波cv2.boxFilter()

方框滤波&#xff08;Box Filtering&#xff09;是一种简单的图像平滑处理方法&#xff0c;它主要用于去除图像中的噪声和减少细节&#xff0c;同时保持图像的整体亮度分布。 方框滤波的原理很简单&#xff1a;对于图像中的每个像素&#xff0c;将其周围的一个固定大小的邻域内…

MySQL安装 找不到 MSVCP100.dll

安装mysql5.6.51时&#xff0c;出现由于找不到 MSVCP100.dll&#xff0c;无法继续执行代码。重新安装程序可能会解决此问题。 这应该是缺少VS运行库文件导致的&#xff0c;运行库就是支持大部分程序运行的基础&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编…

刷题笔记 day2

力扣 1089 复写零 思路&#xff1a;双指针 第一步&#xff1a;利用指针 cur 去记录最后一位要复写的数 &#xff0c; 利用指针 dest 指向最后一位数所要复写的位置&#xff1b; 实现过程&#xff1a;最开始 cur 指向0&#xff0c;dest 指向 -1 &#xff0c; 当arr[cur] ! …

【UEC++学习】UE网络 - Replication、RPC

1. UE网络架构 &#xff08;1&#xff09;UE的网络架构是SC&#xff08;Server - Client&#xff09;的模式&#xff0c;这种模式的优势&#xff1a;这种模式让所有客户端都在服务器端进行安全验证&#xff0c;这样可以有效的防止客户端上的作弊问题。 &#xff08;2&#xff…

Python(五十六)列表元素的排序操作

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

数据结构初阶--栈和队列

目录 一.栈 1.栈的定义 2.顺序栈的功能实现 2.1.顺序栈的定义 2.2.顺序栈的初始化 2.3.顺序栈的判空 2.4.顺序栈的入栈 2.5.顺序栈的出栈 2.6.顺序栈的取栈顶元素 2.7.顺序栈的求栈的大小 2.8.顺序栈的销毁 2.9.完整程序 Stack.h Stack.c test.c 二.队列 1.队…