MySQL事务隔离机制详解

 更新时间:2022年11月21日 16:08:44   作者:天罡gg  
在数据库中,事务是指一组逻辑操作,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位,这篇文章主要介绍了MySQL事务隔离机制,需要的朋友可以参考下

前言

如何控制并发是数据库领域中非常重要的问题之一,MySQL为了解决并发带来的问题,设计了事务隔离机制、锁机制、MVCC机制,用一整套机制来解决并发问题,本文主要介绍事务隔离机制。

一、什么是数据库事务

事务transaction(简写tx),在数据库中,事务是指一组逻辑操作,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与结束之间执行的全部数据库操作组成

事务具有以下4大特性,简称ACID:

1、原子性(Atomicity)
事务是一个原子操作单元,是不可分割的最小工作单元,就像化学中的原子,其对数据的修改,要么全都执行,要么全都不执行

2、一致性(Consistent)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态。
一致性也称作是完整性,就是说事务的执行不能破坏数据库的一致性,在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性

3、隔离性(Isolation)
数据库提供一定的隔离机制,当多个事务并发访问时,保证事务在不受外部并发操作影响的“独立”环境执行,当然了,不同的隔离级别决定了有多“独立”。

4、持久性(Durable)
事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

小结:原子性,持久性大家基本都能秒懂,隔离性也还好大家稍微想想都能理解,就是接下来要讲的隔离级别,但对一致性很多人被官方概念绕住了,其实就是在多事务并发时要保证数据的一致和完整,不理解的话先看下面的问题。

二、事务并发带来的4类问题

1、脏读(Dirty Reads)
事务A读取到了事务B修改但尚未提交的数据,然后事务B回滚了,因此事务A基于此数据做的操作都是无效的,就是读到了“脏”数据(实际上不应该存在的数据),所以叫脏读。

2、脏写或丢失更新(Lost Update)
第一类丢失更新:撤销rollback一个事务时,把其他事务已经提交更新的数据回滚掉了。
第二类丢失更新:提交commit一个事务时,把其他事务已经提交更新的数据覆盖掉了。

3、不可重复读(Non-Repeatable Reads)
在事务A中,按相同的条件执行查询过的sql,返回结果发生了修改或被删除了,这种现象就叫做“不可重复读”。

4、幻读(Phantom Reads)
在事务A中,按相同的条件执行查询过的sql,返回结果中有新数据(是其它事务插入的),就好像发生了幻觉一样,这就叫“幻读”。

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改或删除,幻读侧重于新增。就这个结论网上很多博主写的是不可重复读侧重于修改,幻读侧重于新增或删除 (包括一些知名博主),大家请注意删除不属于幻读,我会在第四段演示时求证。另外后面我会单独安排一篇介绍MVCC机制,到时你自然会明白这里的原因。

三、事务4种隔离级别

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

每种隔离级别可能出现的问题如下:

事务隔离级别脏读不可重复读幻读
读未提交(RU)可能可能可能
读已提交(RC)不可能可能可能
可重复读(RR)不可能不可能可能
串行化(Serializable)不可能不可能不可能

1、读未提交(Read uncommitted,RU)

事务中的修改,即使没有提交,对其他事务也都是可见的,由于可能造成脏读,所以在实际应用中一般很少使用。

2、读已提交(Read committed,RC)

事务A修改并提交的数据才会对其它事务可见,所以解决脏读的问题。大多数数据库系统的默认隔离级别都是读已提交(像Oracle、PostgreSQL、SqlServer,但Mysql不是)。

3、可重复读(Repeatable read,RR)
Mysql默认的事务隔离级别。它保证了在同一个事务中多次读取相同记录的结果是一致的,所以解决了脏读和不可重复读问题,但未彻底解决幻读。

4、串行化(Serializable)

可串行化是最高的隔离级别。它通过强制事务串行执行,避免了前面所说的脏读,不可重复读和幻读问题。简单来说,可串行化会在读取的每一行数据上都加上锁,所以可能导致大量的超时和锁争用问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑用该级别。

四、Mysql演示4种隔离级别

在MySQL中,InnoDB引擎支持事务,MyISAM引擎不支持事务,所以本文实验的测试环境:Windows 10 + MySQL5.7 + InnoDB。
Mysql5.7可以通过命令select @@tx_isolation;语句来查看:

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

设置4种隔离级别的命令:

set tx_isolation='read-uncommitted';
set tx_isolation='read-committed';
set tx_isolation='repeatable-read';
set tx_isolation='serializable';

开始事务:

begin;

提交事务:

commit;

回滚事务:

rollback;

1、读未提交(RU)

set tx_isolation='read-uncommitted';
select @@tx_isolation;
begin;

验证脏读

在这里插入图片描述

2、读已提交(RC)

set tx_isolation='read-committed';
select @@tx_isolation;
begin;

验证解决脏读,存在不可重复读

![在这里插入图片描述](https://img-blog.csdnimg.cn/d4406ad1415c46008d824c48a9c382e6.png

验证幻读

在这里插入图片描述

3、可重复读(RR)

set tx_isolation='repeatable-read';
select @@tx_isolation;
begin;

验证解决脏读和不可重复读
上面说的不可重复读侧重于修改或删除,求证请看下面的截图,

在这里插入图片描述

验证幻读
Mysql的RR级别在一定程度上解决了幻读问题,但不够彻底,至于为什么这么说?还是那句话,得深入理解MVCC机制,这个会单独安排一篇,敬请期待!

在这里插入图片描述

4、串行化(Serializable)

set tx_isolation='serializable';
select @@tx_isolation;
begin;

在这里插入图片描述

如果长时间阻塞,最后会锁等待超时,抛出异常:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
换成是在事务A执行,结果也是一样会阻塞,直到其它事务完成或超时抛出同样的异常。
对于update也是同样的道理,详细如下图:

在这里插入图片描述

总结

通过本文我们已经详细说明了:

事务4大特性:ACID事务并发带来的4类问题:脏读、脏写、不可重复读、幻读事务的4种隔离级别:读未提交、读已提交、可重复读、串行化Mysql提供的4种隔离级别演示

剩下的MySQL锁机制和MVCC机制,我们下文见!

参考文章:

什么是事务?
三分钟图解事务隔离级别,看一遍就懂
MySQL事务隔离级别详解
MySQL的四种事务隔离级别
透彻解读mysql的可重复读、幻读及实现原理
【MySQL (三) | 五分钟搞清楚MySQL事务隔离级别】

到此这篇关于MySQL事务隔离机制的文章就介绍到这了,更多相关mysql事务隔离内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL多层级结构-区域表使用树详解

    MySQL多层级结构-区域表使用树详解

    前面我们大概介绍了一下树结构表的基本使用。在我们项目中有好几块有用到多层级的概念。下面我们哪大家都比较熟悉的区域表来做演示
    2016-07-07
  • 探讨MySQL 保存日期用哪种数据类型

    探讨MySQL 保存日期用哪种数据类型

    在设计数据库表时不可避免的需要用到时间类型,到底选择那种数据类型来表示时间是一个值的讨论的问题,这篇文章主要介绍了MySQL保存日期用哪种数据类型,需要的朋友可以参考下
    2023-08-08
  • MySQL的查询缓存机制基本学习教程

    MySQL的查询缓存机制基本学习教程

    这篇文章主要介绍了MySQL的查询缓存机制基本学习教程,默认针对InnoDB存储引擎下来将,需要的朋友可以参考下
    2015-11-11
  • 浅谈MYSQL中树形结构表3种设计优劣分析与分享

    浅谈MYSQL中树形结构表3种设计优劣分析与分享

    在开发中经常遇到树形结构的场景,本文将以部门表为例对比几种设计的优缺点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 如何设置才能远程登录Mysql数据库

    如何设置才能远程登录Mysql数据库

    本地机器安装的数据库,本地程序可以访问,但是同事的机器却无法连接访问,发现是mysql数据库没有开启远程访问。那么我们需要如何设置呢,这就是本文探讨的内容了
    2014-08-08
  • mysql 5.6.37(zip)下载安装配置图文教程

    mysql 5.6.37(zip)下载安装配置图文教程

    这篇文章主要为大家详细介绍了mysql 5.6.37(zip)下载安装配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • mysql查询表里的重复数据方法

    mysql查询表里的重复数据方法

    这篇文章主要介绍了mysql查询表里的重复数据方法,需要的朋友可以参考下
    2017-05-05
  • MySQL和Redis之间的存储区别

    MySQL和Redis之间的存储区别

    MySQL是一种关系型数据库,而Redis是一种键值对存储数据库,虽然它们都是用来存储和管理数据的,但是它们在很多方面都有不同,本文就给大家详细介绍一下MySQL和Redis之间的存储区别,感兴趣的同学可以参考一下
    2023-06-06
  • 如何更改MySQL数据库的编码为utf8mb4

    如何更改MySQL数据库的编码为utf8mb4

    utf8mb4编码是utf8编码的超集,兼容utf8,并且能存储4字节的表情字符。 这篇文章给大家介绍了更改MySQL数据库的编码为utf8mb4的相关知识,感兴趣的朋友一起看看吧
    2020-02-02
  • Linux中查看MySQL服务是否开启方式

    Linux中查看MySQL服务是否开启方式

    这篇文章主要介绍了Linux中查看MySQL服务是否开启方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09

最新评论