浅谈MySQL数据库的事务隔离级别

事务隔离级别简介

四种事务隔离级别

“读现象” 是在多个事务并发执行时,在读取数据方面可能会出现脏读、幻读、不可重复读的情况。
数据库事务的隔离级别有4种,由低到高分别为 Read uncommitted(读未提交) 、 Read committed (读已提交)、 Repeatable read (可重复读)、 Serializable(序列化),了解它们之间的概念和区别,可以更好的避免问题的出现。

读未提交(READ UNCOMMITTED)

在这种隔离级别下,可能会产生脏读、不可重复读、幻读。
除了容易产生虚幻的读操作和不能重复的读操作外,在这个隔离级的事务可以读到其他事务同级别的事务里还没有提交的数据,如果这个事务使用其他事务不提交的变化作为计算的基础,然后那些未提交的数据被撤销,这就导致了大量的数据错误,从而导致数据不一致。

读已提交(READ COMMITTED)

在这种隔离级别下,可能会产生不可重复读和幻读
在这种事务期间,如果其他事务修改了相应的表行数,那么同一个事务的多个 SELECT 语句可能返回不同的结果。在一个事务内,能看到其他事务提交的数据。

可重复读(REPEATABLE READ)

在这种隔离级别下,可能会产生幻读
在 Mysql 里面,InnoDB 引擎默认的隔离级别是 RR(可重复读),因为它需要保证事务 ACID 特性中的隔离性特征。

序列化(SERIALIZABLE)

在这种隔离级别下,多个并行事务串行化执行,不会产生安全性问题。
这四种隔离级别里面,只有串行化解决了全部的问题,但也意味着这种隔离级别的性能是最低的。

脏读、幻读、不可重复读

事务隔离级别,是为了解决多个并行事务竞争导致的数据安全问题的一种规范。具体来说,多个事务竞争可能会产生三种不同的现象。

脏读

(如图)假设有两个事务 T1/T2 同时在执行,T1 事务有可能会读取到T2 事务未提交的数据,但是未提交的事务 T2 可能会回滚,也就导致了T1 事务读取到最终不一定存在的数据产生脏读的现象。

在这里插入图片描述

不可重复读

(如图)假设有两个事务 T1/T2 同时执行,事务 T1 在不同的时刻读取同一行数据的时候结果可能不一样,从而导致不可重复读的问题。

在这里插入图片描述

幻读

(如图),假设有两个事务 T1/T2 同时执行,事务 T1 执行范围查询或者范围修改的过程中,事务 T2 插入了一条属于事务 T1 范围内的数据并且提交了,这时候在事务 T1 查询发现多出来了一条数据,或者在 T1 事务发现这条数据没有被修改,看起来像是产生了幻觉,这种现象称为幻读。

在这里插入图片描述

总结

MySQL事务隔离级别是指在多个事务同时访问数据库时,数据库如何保证数据的一致性和隔离性,常见的隔离级别如下:

  • 读未提交:最低的隔离级别,允许读取尚未提交的数据变更。
  • 读已提交:允许读取并发事务已经提交的数据。
  • 可重复读:同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改。
  • 串行化:最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。

在实际应用中,需要根据具体情况择合适的离级别,平衡数据的一致性和并发性能,例,在高并发的web应用程序中,可以选择可重复读隔离级别,以保证数据的一致性和并发性能。

  • 脏读(Dirty Reads):事务A读取到了事务B已经修改但尚未想交的数据
  • 不可重读(Non-Repeatable Reads):事务A内部的相同查询语句在不同时刻读出的结果不一致
  • 幻读(Phantomm Reads):事务A读取到了事务B提交的新增数据
隔离级别 并发问题 适用场景
读未提交 可能会导致幻读、脏读或不可重复读 并发性要求不高
读已提交 可能会导致幻读或不可重复读 并发性要求较高
可重复读 可能会导致幻读 数据一致性要求较高
序列化 不会产生干扰 数据一致性要求非常高

隔离级别从上往下,由低到高。隔离级别越高,事务的并发性能就越低。

猜你喜欢

转载自blog.csdn.net/wml_JavaKill/article/details/131768917