化成风 mysql_MySQL数据库事务剖析

2023-10-09 17:20

本文主要是介绍化成风 mysql_MySQL数据库事务剖析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MySQL数据库事务剖析

事务就是一组原子性的SQL查询,是一个独立的执行单元。事务内的语句,要么全部执行成功,要么全部执行失败。

1、事务的标准特征

一个运行良好的事务处理系统,必须具备原子性、一致性、隔离性、持久性。

原子性:一个事务必须被视为一个不可分割的最小工作单元,这个事务的所有操作要么全部提交成功,要么全部失败回滚。

一致性:数据库总是从一个一致性的状态转换到另外一个一致性状态。比如在一个事务中执行一组sql,其中一个执行失败,因为事务最终没有提交,所以事务中所做的修改也不会保存到数据库中。

隔离性:通常来说,一个事务所做的修改在最终提交之前,对其他事务是不可见的。

持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中。

2、隔离级别

在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

未提交读:

在此级别中,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读。

提交读:

此级别是大多数数据库系统的默认隔离级别。此级别满足前面提到的隔离性的简单定义:一个事务开始时,只能看见已经提交的事务所做的修改。换言之,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫做不可重复读。比如:A事务第一次读取数据,然后B事务更改该数据并提交,A事务再次读取数据,两次读取的数据不一样。

可重复读:

此级别是MySQL的默认级别。基于提升并发性能的考虑,MySQL的InnoDB存储引擎实现的都不是简单的行级锁,而是多版本并发控制(MVCC),MVCC可以被认为是行级锁的变种,但是它却避免了很多情况下的加锁操作,因此开销更低。MVCC 的实现是通过保存数据在某个时l同点的快照来实现的。InnoDB的MVCC是通过在每行记录后面保存两个隐藏 的列来实现的。这两个列,一个保存了行的创建时间 ,一个保存行的过期时间 (或删除时间)。有赖于MVCC,同一个事务中的查询只能返回版本号不高于当前事务版本的数据,即事务只能看到该事务开始前或者被该事物影响的数据。即防止了不可重复读的发生。

依靠上面的机制,已经做到了在事务内数据内容的不变,但是不能保证多次查询得到的数据数量一致。因为在一个事务执行的过程中别的事务完全可以执行数据插入,当插入了刚好符合查询条件的数据时,就会引发数据查询结果集增加,引发幻读。InnoDB提供的间隙锁机制可以在一定程度上防止幻读的发生。

可串行化:

此级别是最高的隔离级别,它通过强制事务串行执行,避免了前面所说的幻读的问题。简单地说,可串行化会在读取地每一行数据上加锁,所以可能导致大量的超时和锁争用的问题。实际应用中很少用到此级别。

3、死锁

死锁是两个或者多个事务在同一个资源上互相占用,并请求锁定对方占用的资源,从而导致恶性循坏的过程。当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁。如下所示:

事务A:

1b80ed7593f497300305718c5184cc4f.png

事务B:

bc5456ccf4a5a9752e265cdba5ba5c5d.png

如果两个事务都执行了第一条update语句,更新了一行数据,同时锁定了该行数据,然后这两个事务又尝试去执行第二个update语句,但是发现该行数据已经被对方锁定,然后都等待对方释放锁,同时持有对方需要的锁,则陷入死循环。死锁发生以后只有部分或完全回滚一个事务才能打破死锁。

为解决死锁,数据库往往会实现各种死锁检测和死锁超时机制。

4、事务日志

事务日志可以提高事务的效率。使用事务日志,存储引擎在修改表的数据时,只需要修改其内存拷贝,再把该修改行为持久化到磁盘上的事务日志中,而不需要每次都将数据持久到磁盘。事务日志采用追加的方式,写日志的操作是磁盘上一小块区域内的顺序IO,而不像随机IO需要在磁盘的多个地方移动磁头。事务日志持久化以后,内存中被修改的数据被慢慢刷回磁盘。这种方式称为预写式日志,Innodb通过此方式来保证事务的完整性。

如果数据的修改被持久化到事务日志,而数据本身还没有被写回磁盘,此时系统崩溃,则存储引擎存重启以后会自动恢复这部分被修改的数据。

Innodb事务日志包括:重做日志redo和回滚日志undo。

Redo记录的是已经全部完成的事务,就是执行了commit的事务,记录文件是ib_logfile0 ib_logfile1。Undo记录的是已部分完成并且写入硬盘的未完成的事务,默认情况下回滚日志是记录下表空间中的。

一般情况下,mysql在崩溃之后,重启服务,innodb通过回滚日志undo将所有已完成并写入磁盘的未完成事务进行rollback,然后redo中的事务全部重新执行一遍即可恢复数据。

5、MySQL事务处理的方法

(1)、用begin,rollback,commit来实现

begin 开始一个事务

rollback 事务回滚

commit  事务确认

如下图所示:

22d348e784832aaacd216160d46c5156.png

(2)、默认采用自动提交模式

如果不是显式的开启一个事务,则每个查询都当作一个事务执行提交操作。在当前连接中可以通过设置variables来启用或者禁用自动提交模式。

查看当前系统的自动提交是否开启:show variables like "autocommit%";

373930a88c330609741e1a76d14659c0.png

如上图所示:1或者ON表示启用,0或者OFF表示禁用。

我们可以通过

set autocommit=0   禁止自动提交

set autocommit=1 开启自动提交

来实现事务的处理。

如下图所示:

364a58958e913c3536d1a6ffbbe5bd03.png

这篇关于化成风 mysql_MySQL数据库事务剖析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/174385

相关文章

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

SQL server数据库如何下载和安装

《SQLserver数据库如何下载和安装》本文指导如何下载安装SQLServer2022评估版及SSMS工具,涵盖安装配置、连接字符串设置、C#连接数据库方法和安全注意事项,如混合验证、参数化查... 目录第一步:打开官网下载对应文件第二步:程序安装配置第三部:安装工具SQL Server Manageme

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

浅谈mysql的not exists走不走索引

《浅谈mysql的notexists走不走索引》在MySQL中,​NOTEXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引,下面就来介绍一下mysql的notexists走不走索... 在mysql中,​NOT EXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引。以下

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys