浅入浅出MySQL事务

news2024/9/23 23:23:04

什么是事务

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

事务的逻辑单元中可以是一条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.coloradmin.cn/o/817945.html

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

相关文章

vue 修改端口号

在根目录创建一个vue.config.js文件夹 module.exports {lintOnSave: false,devServer: {port: 3000,open: true} }运行后

降压IC 外置MOS DC48V转24V 3A 30V-80V转24V 3A 高压大功率

摘要:本文介绍了AH8A50QA降压IC外置MOS芯片方案,可将输入电压范围从30V至80V和9V至100V转换为24V输出,并提供最大3A的输出电流。该芯片方案采用了内置MOS管和QFN-20封装,适用于电动车和汽车车载充电源等高压大功率应用场景。 随着…

Cpp6 — 模板

模板:这里有一个概念:泛型编程---针对广泛的类型去写代码编程。之前都是针对具体的类型进行编程。 模板分为函数模板和类模板。 函数模板 当我们想要使用一个swap可以用作多种类型时,可以使用模板。这样我们就可以不使用重载,不…

商城小程序踩坑(一):iPhone 11、iPhoneX 等设备底部安全区域/小黑条适配

一、前言 这两天正在开发商城小程序-商品详情页,在做设备测试的时候突然发现详情页底部—— 购物车 和 购买区域在苹果手机上不适配,并且还存在小黑条。 底部功能没有办法正常使用。 如下图所示: 解决后效果,如下图所示&#xff…

Swagger之Hello World !

目录 ■1.前言・Swagger介绍 ■2.例子,如果基于Spring Boot项目,实现Swagger---非常简单 2.1.已有的SpringBoot项目 2.2.修改POM文件 2.3.添加Config文件…

html请求谷歌音频跨域问题(谷歌翻译接口)虚拟机ping不通google(下载谷歌音频、下载百度翻译音频)

文章目录 调用谷歌翻译接口,尝试了几种方案,都提示跨域不行第一种(通过js代码获取音频文件的Blob对象,提示跨域了)代码结果 第二种(尝试新窗打开音频url,404,估计也是跨域了&#xf…

StarRocks Friends 广州站精彩回顾

上周六,StarRocks & Friends 活动在羊城广州成功举行,社区的小伙伴齐聚一堂,共同探讨了 StarRocks 在业界的应用实践和湖仓一体等热门话题。 本文总结了技术交流活动的关键内容和视频资料,感谢社区每一位小伙伴的支持和参与&…

如何提高接口测试覆盖率?

接口测试是测试系统组件间接口的一种测试。 接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。 测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。 接口测试该如何提高测试的覆盖率呢&#…

PCL点云处理之最小二乘空间直线拟合(3D) (二百零二)

PCL点云处理之最小二乘空间直线拟合(3D) (二百零二) 一、算法简介二、实现代码三、效果展示一、算法简介 对于空间中的这样一组点:大致呈直线分布,散乱分布在直线左右, 我们可采用最小二乘方法拟合直线,更进一步地,可以通过点到直线的投影,最终得到一组严格呈直线分布…

软件测试一周面试十家公司,分享面试经历

从开始面试讲起,公司规模我分成5类:创业公司0-20人,小型公司20-40人,中小型50-99,中型公司100-499即将上市的那种,已上市公司100-499。 创业公司 第一个面试的那家创业公司特别坑,开始面试&am…

4年测试“我“该何去何从?测试还是测试开发?

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 4年测试&#xff…

秋招备战笔试Day2

目录 单选 1.A 派生出子类 B , B 派生出子类 C ,并且在 java 源代码有如下声明: 2.下面代码将输出什么内容:() 3.阅读如下代码。 请问,对语句行 test.hello(). 描述正确的有(&…

vlan access, trunk, hybrid (tagged/untagged) 笔记

vlan 接口和配置 PVID(port vlan ID) 定义 pvid 主要目的: 当交换机接口收到没有 vlan tag 标签的包时,接口会将定义的 pvid 作为当前包的 vlan id。当对映 pvid vlan 的包,通过当前交换机接口发出时,接…

ADSelfService Plus:保护密码安全的最佳解决方案

密码安全是当今数字时代中至关重要的话题。随着互联网和信息技术的迅速发展,我们的生活变得越来越数字化,密码已成为我们生活中不可或缺的一部分。然而,随着各种网络威胁和黑客攻击不断增加,保护我们的密码变得越来越重要。 密码安…

测试工程师刚入职如何快速熟悉需求并输出测试用例?

刚入职第一天,早上办完入职,下午就就分配了测试任务,2个模块13条短信验证,2天内输出测试用例(xmind输出功能点,excel书写业务流)。测试负责人给我们快速讲了一下业务,在这过程中大概…

openssl/bn.h: No such file or directory

报错截图 解决方法 ubuntu apt install libssl-dev -y centos yum install openssl-devel -y

echarts实现多层环图(复制粘贴即可)

data里面参数配置: // 多重环图optionCircle: {tooltip: {show: false,trigger: item,formatter: "{a} : {c} ({d}%)"},color: [#3AB1EB, #D48B6A, #5B41C8, #FE7E02],legend: {orient: horizontal,itemWidth: 30, // 图例标记的图形宽度。itemHeight…

从产品和运营的角度聊聊,如何有效吸引与引导用户注册转化?

从产品和运营的角度聊聊 如何有效吸引与引导用户注册转化? 正文共:4360字 23图 预计阅读时间:11分钟 1 如何进行改版,找找思路? 前段时间在做公司的网站改版策划,此前接触的都是一些ToB的解决方案提供商…

Jmeter脚本录制:抓取IOS手机请求包

现在移动端的项目越来越多,今天给大家介绍一下,在IOS下Jmeter如何抓包。 1、电脑连上wifi 2、Jmeter中配置“HTTP代理服务器” 1)启动Jmeter;2)“测试计划”中添加“线程组”;3)“测试计划”中添加“HTTP代理服务器”&#xff…

【算法很美】多维数组和字符串篇打卡(第三天)

文章目录 子矩阵的最大累加和整体代码 矩阵运算-乘法整体代码 检测字符串是否有重复字符整体代码 反转字符串整体代码 变形词整体代码 替换字符串中的空格整体代码 子矩阵的最大累加和 整体代码 package 每日算法学习打卡.算法打卡.七月份.七月三十一号;import java.util.Arra…