IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL事务隔离级别(2022.05.15) -> 正文阅读

[大数据]MySQL事务隔离级别(2022.05.15)

事务是什么?

一般是指要做的或所做的事情

为什么要引入事务?

为了保证工作流程中操作的数据的可靠性

原子性(Atomicity):指的是事务是一个不可分割的单位,要么事务中的所有的操作全部成功,要么全部失败;——操作层面

一致性(Consistency):和原子性类似,只不过在数据层面。指的是事务必须在执行前后满足数据库的所有约束。(这个约束我认为是指:有一个操作,其中A,B,C三步都需要修改数据,那么这三步操作数据要么都成功,要么都失败。成功或者失败得到的数据结果就代表数据库的约束)

隔离性(isolation):不同事务之间的操作,互不影响

持久性(durability):数据一经提交永久保存

目录

1.隔离性

1.1 读未提交

1.2 读已提交

1.3 可重复读

1.4 可串行化


1.隔离性

隔离性分为四个隔离级别:读未提交、读已提交,可重复读、串行化。

事务的隔离级别

由上图我们可得知不同隔离级别带来的问题。

下面,让咱们来亲自动手试试,毕竟不断地重复才能加深我们的映像!话不多说,开始

查看当前事务隔离级别

select @@tx_isolation;

先创建一个表,丢几条数据进去

CREATE TABLE `account` ( 
`id` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(255) DEFAULT NULL, 
`balance` int(11) DEFAULT NULL, 
PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `account` (`name`, `balance`) VALUES ('lilei', '450');
INSERT INTO `account` (`name`, `balance`) VALUES ('hanmei', '16000');
INSERT INTO `account` (`name`, `balance`) VALUES ('lucy', '2400');

1.1 读未提交

根据上图可知,读未提交这个隔离级别是最低级的隔离级别了。

它会造成:脏读、不可重复读、幻读。

咱们来看看脏读是怎么一回事:

脏读:事务A读取到了事务B修改但未提交的数据

先设置隔离级别为读未提交

set tx_isolation='read-uncommitted';

咱看看原始的数据先

客户端A开启事务

修改数据;但还未提交

客户端B开启事务之后查看,发现此时,读到了客户端A修改但是还未提交的数据。

?然后客户端A操作回滚

客户端B再去查询,发现依旧读取到了未提交的数据

以上现象就是脏读

1.2 读已提交

在该隔离级别中,会造成:不可重复读、幻读;

不可重复读:当前事务在单位时间内连续两次读取数据,发现两次读到的数据结果都不一致;

首先,先将隔离级别改为读已提交

set tx_isolation='read-committed';

然后,在客户端A开启事务改动数据,但是不提交

?在客户端B查询

此时我们发现,客户端B读取到的还是之前的数据,并未读到事务1修改但未提交的数据,避免了脏读现象。

接着,客户端A提交事务

在客户端B中进行查询,发现两次得到的结果不一样

这就是不可重复读

1.3 可重复读

在可重复读这一隔离级别,会产生幻读

幻读:简单来说,就是在当前事务进行读操作,第一次读,发现总共有3条数据。第二次读,就发现有不等于3条数据的数量。

咱们先将隔离级别改为可重复读(MySQL默认的隔离级别

set tx_isolation='repeatable-read';

先试试,能不能解决不可重复读呢?

在客户端A中开启事务修改数据,然后提交事务。

?然后在客户端B中进行查看

?发现不可重复读问题已经解决了。

咱们再来看看,幻读的问题

客户端A新增一条数据之后,提交事务

客户端B进行查询

?发现两次读到的数据条数不一样了,这就是幻读;

1.4 可串行化

这是最高等级的隔离级别,能够解决所有问题。

设置隔离级别

set tx_isolation='serializable';

客户端A上进行查询操作,针对id=1的数据

?然后在客户端B进行更新,也针对id=1的数据

?但是呢,发现id=1的数据已经被锁了。

咱们来试试id=2的数据,能否被修改吗。

?发现是没有问题。

那么先修改再查询呢?

?

还是不行。。。。

那是为什么会这样呢?先上结论

如果客户端A执行的是一个范围查询,那么该范围内的所有行包括每行记录所在的间隙区间范围(就算该行数据还未被插入也会加锁,这种是 间隙锁 )都会被加锁。此时如果客户端B在该范围内插入数据都会被阻塞,所以就避免了幻读。
感觉有点乱呢,让我们通过例子来理一理
这是咱们的数据

id为1,4,6.? 那么对应的区间是[1,4],[4,6],[6,+∞)

客户端A修改id>1且id<7的数据

客户端B查询id=4的数据

?发现无法查询,其原因就是因为间隙锁将对应区间的数据给锁住了。别着急,接着往下看

再来试试,客户端A修改id>1且id<5的数据

事务2查询id=6的数据

发现还是锁住了,咋不对呢?我明明没有修改这个范围内的数据啊!

这就是所谓的间隙锁了

刚刚提到,咱们当前数据对应的区间是[1,4],[4,6],[6,+∞)。那我修改的是(1,5)的数据,为啥还是不能修改id=6的数据呢?

原因就是因为id=6的数据,在[4,6]这个区间。所以,id=6这条数据就被锁住了。

那么id=7的数据可以插入吗?

那么咱们继续试试嘛,插入一条id=7的数据。

插入成功之后,客户端A还是修改区间(1,5)的数据

客户端B我们来查询id=7的数据,以及查询id=4的数据

按照上图的结果,可以验证我们刚才所说的,间隙锁锁住的区间。所以id=7可以查询,id=4不能。

~stay hungry,stay foolish

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:42:19  更:2022-05-18 17:44:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:09:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码