化成风 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

相关文章

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

SpringKafka消息发布之KafkaTemplate与事务支持功能

《SpringKafka消息发布之KafkaTemplate与事务支持功能》通过本文介绍的基本用法、序列化选项、事务支持、错误处理和性能优化技术,开发者可以构建高效可靠的Kafka消息发布系统,事务支... 目录引言一、KafkaTemplate基础二、消息序列化三、事务支持机制四、错误处理与重试五、性能优

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法

《mysql出现ERROR2003(HY000):Can‘tconnecttoMySQLserveron‘localhost‘(10061)的解决方法》本文主要介绍了mysql出现... 目录前言:第一步:第二步:第三步:总结:前言:当你想通过命令窗口想打开mysql时候发现提http://www.cpp

MySQL大表数据的分区与分库分表的实现

《MySQL大表数据的分区与分库分表的实现》数据库的分区和分库分表是两种常用的技术方案,本文主要介绍了MySQL大表数据的分区与分库分表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. mysql大表数据的分区1.1 什么是分区?1.2 分区的类型1.3 分区的优点1.4 分

MySQL错误代码2058和2059的解决办法

《MySQL错误代码2058和2059的解决办法》:本文主要介绍MySQL错误代码2058和2059的解决办法,2058和2059的错误码核心都是你用的客户端工具和mysql版本的密码插件不匹配,... 目录1. 前置理解2.报错现象3.解决办法(敲重点!!!)1. php前置理解2058和2059的错误

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

MySQL Workbench 安装教程(保姆级)

《MySQLWorkbench安装教程(保姆级)》MySQLWorkbench是一款强大的数据库设计和管理工具,本文主要介绍了MySQLWorkbench安装教程,文中通过图文介绍的非常详细,对大... 目录前言:详细步骤:一、检查安装的数据库版本二、在官网下载对应的mysql Workbench版本,要是

mysql数据库重置表主键id的实现

《mysql数据库重置表主键id的实现》在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,本文主要介绍了mysql数据库重置表主键id的实现,具有一定的参考价值,感兴趣的可以了... 目录关键语法演示案例在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,当我们