MySQL | 事务 | 脏读 | 不可重复读 | 幻读 | 隔离级别

目录

一.事务

1.什么是事务

2.事务所具有的四个特性

3.原子性

4.一致性

5.隔离性

二.脏读

1.什么是脏读

2.导致脏读发生的情况

三.不可重复读

1.不可重复读

2.不可重复读问题发生的情况

3.解决不可重复读问题的方法

四.幻读

1.什么是幻读

2.幻读发生的情况

3.解决方法

五.持久性

六.隔离级别

1.隔离级别的分类

2.隔离级别的划分


一.事务

1.什么是事务

我们一般所讲的事务,是MySQL中InnoDB存储引擎所支持的事务。而所谓的事件简单的来讲几就是一组特定SQL语句的集合。

2.事务所具有的四个特性

  1. 原子性:一个事务是一个不可分割的工作单位,事务中包括的操作要么都做(某个语句的集合要么全部执行成功),要么都不做(某个语句的集合要么全部执行失败)。如果某一步执行失败了,事务就会回滚到语句执行前的状态。
  2. 一致性:完整性约束,数据完整性约束指的是为了防止不符合规范的数据进入数据库,在用户对数据进行插入、修改、删除等操作时,DBMS自动按照一定的约束条件对数据进行监测,使不符合规范的数据不能进入数据库,以确保数据库中存储的数据正确、有效、相容。
  3. 隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持久性:事务执行的结果在磁盘上永久的保存,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

这四个属性通常称为ACID特性。

3.原子性

日志系统中有两个日志,分别是

  • 重做日志(redo log)
  • 未做日志(undo log)

首先事务在提交以后,重做日志先记录这个事务将要执行的操作,接着进行日志先行,就是将现在重做日志中存储的信息刷新到磁盘上,接着才开始执行事务。假如事务A执行到某一步骤时,系统断电了,但恢复电力后可以通过重做日志来查看事务A一共进行了哪些操作以及执行到了哪一个步骤。即重做日志保证了事务全部执行成功。

未做日志用来记录了每一个修改点的状态(版本),通俗的理解为每一条数据被修改前和修改后的值。这样的话,就可以进行事物的回滚了(回到数据一开始的状态)。即未做日志保证了事务全部执行失败。

通过这两个日志就保证了事务的原子性。

4.一致性

与原子性密切相关,但是一致性是一个很难理解的概念,如有兴趣大家可以参考一下这篇博客:

https://blog.csdn.net/qq_26295547/article/details/79828966

以及知乎的相关回答:

https://www.zhihu.com/question/31346392

5.隔离性

如果没有隔离性,事务执行过程中会出现什么问题?

出现脏读,例如现在在数据库的某张表中有这样一条数据

name salary
zhangsan 5000

这条数据的意思是zhangsan的工资为5000。现在有一个事务A开始执行,首先事务A进行以下操作

/*A---Begin*/

select *
from table_name
where salary = 5000;

updata table_name
set salary = 8000
where name = zhangsan;

当执行到这里时,事务A已经将zhangsan的工资修改为了8000,但此时因为时间轮片法的规则,给事务A分配的时间到了(此时事务A的执行并没有结束),而此时系统开始执行另一个事务B,事务B进行了下面操作

/*B-----Begin*/

select *
from table_name
where salary = 8000;

此时事务B查找到的结果是 zhangsan的工资为8000,接着事务B又对这一条数据进行了其他一系列操作,因为时间轮片法的规则,给事务B分配的时间到了(此时事务B的执行并没有结束),此时系统又开始执行事务A,若此时事务A又对这条数据进行了其他操作,但某一步执行失败了,根据事务的原子性,事务A就要回滚到语句执行前的状态。回滚后 zhangsan的工资又变成了5000,而此时另一个事务B所有的操作都是建立在 zhangsan 的工资为8000的基础上,这是事务B所读到的数据都是脏数据,而基于脏数据所进行的操作都是错误的,这种情况就是脏读。

/*用户自己执行回滚*/

roolback;

二.脏读

1.什么是脏读

脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。

2.导致脏读发生的情况

事务执行过程中获取到其他事务执行过程中的结果。

三.不可重复读

1.不可重复读

还是同样的数据

name salary
zhangsan 5000

同样事务A执行以下操作

/*A---Begin*/

select *
from table_name
where salary = 5000;

updata table_name
set salary = 8000
where name = zhangsan;

接着事务B开始执行(此时事务A并没有执行结束),事务B进行了以下操作

/*B-----Begin*/

select salary
from table_name
where name = zhangsan;

此时事务B得到的结果是 zhangsan的工资为5000,接者系统又开始执行事务A,事务B暂时被挂起,而此时事务A什么操作都没有进行,接这事务A就结束了。

/*A------End*/

而系统又开始执行事务B,若现在事务B有查询了一次 zhangsan 的工资

select salary
from table_name
where name = zhangsan;

而此时,zhangsan的工资已经被事务修改为了8000,所以事务B的这次查询操作得到的结果就是zhangsan的工资为8000,我们发现B事务什么事情都没有做,只是对同一条数据进行了两趟查询操作,却拿到了两条不同的数据。这种问题就被称为不可重复读(在同一个事务中,对于同一份数据读取到的结果不一致。

2.不可重复读问题发生的情况

事务在执行过程中获取到了其他不同阶段的结果,是修改(updata)操作导致的。

3.解决不可重复读问题的方法

不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这回导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,避免不可重复读。

四.幻读

/*A-----Begin*/

insert into table_name
values(lisi,5000);
/*B-----Begin*/
select COUNT(name)
from table_name
where salary = 5000;
/*A-----End*/
select COUNT(name)
from table_name
where salary = 5000;

/*B-----End*/

我们看到,首先执行事务A,事务A向这张表里插入了一条数据,接着事务A被挂起,事务B开始执行,事务B查询了工资为5000的员工的个数,的到的结果是1,接着事务B被挂起,事务A有开始执行,此时事务A没有进行其他操作,而是事务A执行完毕并关闭,接着事务B又开始执行,此时事务B又查询了工资为5000的员工的个数,但得到的结果是2,。

1.什么是幻读

在同一个事务中,同一个查询多次返回的结果不一致。

2.幻读发生的情况

事务执行过程中获取到了其他事务不同阶段的结果,是由插入(insert)和删除(delete)导致的。

3.解决方法

间隙锁,幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。

五.持久性

通过日志来保证事务的持久性。

六.隔离级别

1.隔离级别的分类

  • 未提交读(READ-UNCOMMITTED),最低的隔离级别,在这个隔离级别下出现脏读,不可重复读,幻读的问题。
  • 已提交读(READ-COMMITTED),SQL Server默认的隔离级别就是已提交隔离级别。在这个隔离级别下出现 不可重复读,幻读的问题,可以解决脏读的问题
  • 可重复读(REPEATABLE-READ),InnoDB存储引擎默认的隔离级别就是可重复读隔离级别。在这个隔离级别下出现幻读的问题,可以解决脏读吧,不可重复读问题。
  • 可序列化,隔离级别最高,不会出现上面所述的任何问题,但是效率太低,因为在这种隔离级别下事务之间的关系是串型的,牺牲了系统的并发性。

可以通过下面命名查看当前系统的隔离级别

select @@tx_isolation;

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

set tx_isolation = "READ-UNCOMMITED";

2.隔离级别的划分

  • 全局隔离级别:默认为REPEATABLE-READ,存放在服务器端。
  • 会话隔离级别: 会话隔离级别是复制的服务器端的隔离级别。而客户端看到的都是会话隔离级别。所以就算用户将某一会话的隔离级别改变了,其他会话的隔离级别不会改变。
发布了88 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ThinPikachu/article/details/105488745