MySQL的事务隔离级别

目录

事务隔离级别的概念

[脏读(Dirty Read):](#脏读(Dirty Read):)

[不可重复读(Non-Repeatable Read):](#不可重复读(Non-Repeatable Read):)

[幻读(Phantom Read):](#幻读(Phantom Read):)

[读未提交(Read Uncommitted)](#读未提交(Read Uncommitted))

读未提交隔离级别的特点

示例

优势和劣势

[读已提交(Read Committed)](#读已提交(Read Committed))

读已提交隔离级别的特点

示例

优势和劣势

[可重复读(Repeatable Read)](#可重复读(Repeatable Read))

可重复读隔离级别的特点

示例

优势和劣势

串行化(Serializable)

串行化隔离级别的特点

示例

优势和劣势


当涉及到数据库事务时,事务隔离级别是一个重要的概念,它决定了事务之间的相互影响程度。MySQL支持四种不同的事务隔离级别,分别是读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。本文将详细介绍这些隔离级别,以及它们对数据库操作的影响。

事务隔离级别的概念

事务隔离级别是数据库管理系统(DBMS)用来控制多个事务之间互相干扰的级别。在多个事务同时运行时,一个事务的操作可能会影响到其他事务的结果,因此需要一种机制来管理这种互相干扰。不同的隔离级别提供了不同程度的隔离,以满足不同的应用需求。

MySQL定义了以下四种事务隔离级别:

  1. 读未提交(Read Uncommitted):最低级别,允许一个事务读取另一个事务尚未提交的数据。这可能导致脏读、不可重复读和幻读的问题。

  2. 读已提交(Read Committed):允许一个事务只读取其他已提交事务的数据。这可以避免脏读,但仍可能出现不可重复读和幻读的问题。

  3. 可重复读(Repeatable Read):默认隔离级别。在一个事务中,多次读取同一数据会得到相同的结果,即使其他事务对该数据进行了修改。这可以避免脏读和不可重复读,但可能出现幻读问题。

  4. 串行化(Serializable):最高级别,要求事务串行执行,即事务之间没有并发。可以避免脏读、不可重复读和幻读,但会影响并发性能。

脏读(Dirty Read)、不可重复读(Non-Repeatable Read)和幻读(Phantom Read)是与数据库隔离级别相关的三种问题,它们可能会导致数据的一致性问题,下面我举例介绍一下它们🤗:

脏读(Dirty Read)

定义:脏读是指一个事务读取到了另一个事务尚未提交的数据,当那个事务最终回滚时,读取的数据就变得无效或"脏"了。

示例:假设有两个银行账户,Alice 和 Bob。Alice 想要转账给 Bob 1000美元,但在她的事务还没有提交之前,Bob 的查询可能会显示他的余额增加了1000美元。然而,如果 Alice 的事务最终回滚,Bob 实际上并没有得到这1000美元。

不可重复读(Non-Repeatable Read)

定义:不可重复读是指在同一个事务中,多次读取相同数据时,得到了不同的结果。这是因为在事务执行期间,其他事务修改了数据。

示例:假设小明正在查询某本书的价格,结果是50美元。然后,他再次查询,但在这之间,另一个用户购买了这本书并将价格提高到100美元。因此,小明两次查询相同的数据得到了不同的结果,这就是不可重复读。

幻读(Phantom Read)

定义:幻读是指在同一个事务中,多次执行相同的查询,但由于其他事务插入新数据或删除现有数据,每次查询返回的结果集不一样。

示例:考虑一个图书馆数据库,小红正在查询某个作者的所有书籍。第一次查询返回了5本书,但在事务执行期间,另一个用户添加了一本新书,所以在第二次查询时,返回了6本书。这就是幻读,因为查询结果集似乎发生了变化,尽管小红的事务并没有修改任何数据。

不可重复读幻读 区别在于不可重复读通常涉及到已存在数据的修改,而幻读涉及到数据的插入或删除,导致查询结果集的不一致性。


下面我会举出例子来详细介绍这四种隔离级别~~😁

读未提交(Read Uncommitted)

读未提交(Read Uncommitted)是事务隔离级别中最低的级别,也是最不严格的级别。在这个级别下,一个事务可以读取到其他事务尚未提交的修改,甚至是"脏数据"。这意味着在读未提交隔离级别下,数据的一致性和完整性可能受到破坏,因为其他事务的未提交更改可能会影响到正在运行的事务。以下是读未提交隔离级别的详细介绍和举例说明其优劣势。

读未提交隔离级别的特点

最低隔离级别:读未提交是MySQL中隔离级别中最低的级别,事务之间的隔离程度最低。

允许脏读:在读未提交隔离级别下,一个事务可以读取到其他事务尚未提交的数据修改,这种读取被称为"脏读"。脏读意味着一个事务可能会看到其他事务的临时更改,这些更改后来可能会被回滚。

高并发性:由于读未提交允许多个事务同时读取和修改相同的数据,因此在高并发环境下可以提供较好的性能。

示例

假设有两个人,小明和小红,他们共享一个可编辑的电子文档,比如一个共享笔记本。

  1. 小明正在编辑文档,他写了一句话:"明天要去购物。"
  2. 在小明提交他的编辑之前,小红开始查看文档。
  3. 由于"读未提交"的情况,小红可以看到小明写下的未提交的内容,即"明天要去购物"。

结果是,小红在她的查看中看到的文档内容与实际情况不符,因为她可以读取到小明的未提交修改。如果小明最终决定不去购物并将文档修改为"明天要去看电影",那么小红看到的内容将是不准确的,因为她在小明提交修改之前就已经看到了未提交的信息。

优势和劣势

优势:

高并发性:读未提交隔离级别允许多个事务同时读取和修改数据,因此在高并发环境下可以提供较好的性能。

劣势:

  1. 脏读:最大的劣势是允许脏读,即一个事务可以读取到其他事务未提交的更改。这可能导致不一致的数据状态。

  2. 丢失更新:读未提交隔离级别还可能导致"丢失更新"问题,其中一个事务的更改可能会被另一个事务覆盖,因为它们同时修改相同的数据。

  3. 数据不一致性:读未提交隔离级别不提供数据一致性保证,因此对于需要严格数据一致性的应用来说,它通常是不合适的。

在大多数情况下,读未提交隔离级别都不建议使用,因为它的风险往往超过了性能优势。通常情况下,较高级别的隔离级别如"读已提交"或"可重复读"更适合大多数应用,因为它们提供了更好的数据一致性保证,同时仍具备良好的性能。只有在极少数特殊情况下,才会考虑使用读未提交隔离级别。

读已提交(Read Committed)

读已提交(Read Committed)是一种常见的事务隔离级别,它提供了一定程度的隔离,以确保事务之间不会读取到未提交的数据更改。接下来,我将详细介绍读已提交隔离级别,并提供一个示例来说明其优劣势。

读已提交隔离级别的特点

隔离程度: 读已提交隔离级别确保一个事务只能读取到已经提交的数据更改,不会读取到其他事务尚未提交的更改。这提供了一定程度的数据隔离,防止脏读问题的发生。

避免脏读: 读已提交隔离级别避免了脏读问题,即一个事务不会读取到其他事务未提交的数据更改。但仍可能出现不可重复读和幻读的问题。

示例

假设有一个在线商店的数据库,其中包含产品和订单信息。

  1. 用户A正在查询某个产品的库存数量。

  2. 与此同时,用户B正在执行一个任务,将该产品的库存数量减少5个单位。

  3. 在读已提交隔离级别下,用户A的查询操作只能读取到已经提交的库存数量,而不会读取到用户B尚未提交的减少5个单位的更改。

  4. 如果用户B成功完成并提交了任务,那么下一次用户A的查询将反映减少的库存数量。

优势和劣势

优势:

避免脏读: 读已提交隔离级别确保一个事务不会读取到其他事务尚未提交的数据更改,从而避免了脏读问题。

劣势:

不可重复读: 读已提交隔离级别允许不可重复读问题的发生。不可重复读是指在同一事务内的两次查询返回了不同的结果,这可能在某些情况下需要应用层面的处理来处理。

总之,读已提交隔离级别在绝大多数应用中是一个合理的选择,因为它提供了一定程度的隔离,同时避免了脏读问题。然而,如果应用需要更高的隔离级别,可以考虑使用更高级别的隔离级别,如"可重复读"。

可重复读(Repeatable Read)

可重复读(Repeatable Read)是一种事务隔离级别,提供了更高程度的隔离,以确保在同一事务内多次查询返回一致的结果。接下来,我将详细介绍可重复读隔离级别,提供一个示例来说明其优劣势。

可重复读隔离级别的特点

隔离程度: 可重复读隔离级别确保一个事务在执行期间可以多次读取相同的数据,并且不会受到其他事务的影响。这提供了高度的数据隔离,避免了脏读、不可重复读和幻读问题。

避免脏读: 可重复读隔离级别避免了脏读问题,即一个事务不会读取到其他事务未提交的数据更改。

避免不可重复读: 可重复读隔离级别确保在同一事务内的两次查询返回一致的结果,避免了不可重复读问题。

示例

假设有一个银行的数据库,其中包含账户余额的数据。

  1. 用户A正在执行一个转账操作,将100美元从他的账户转移到用户B的账户。

  2. 同时,用户B正在查询他的账户余额。

  3. 在可重复读隔离级别下,用户B的查询操作只能读取到事务开始时的账户余额,不会读取到用户A的转账操作尚未提交的更改。

  4. 即使用户A成功执行了转账操作并提交了事务,用户B的查询操作仍然只能看到事务开始时的余额。

优势和劣势

优势:

高度隔离: 可重复读隔离级别提供了高度的隔离,确保在同一事务内的多次查询返回一致的结果,避免了脏读、不可重复读和幻读问题。

数据一致性: 可重复读隔离级别确保事务内的查询不受其他事务的干扰,从而维护了数据的一致性。

劣势:

并发性降低: 由于提供了更高的隔离,可重复读隔离级别可能导致并发性降低,因为多个事务之间无法同时访问相同的数据。

总之,可重复读隔离级别通常在需要高度数据隔离和一致性的应用中是一个合理的选择。然而,它可能会导致并发性降低,因此在某些情况下,需要权衡选择适当的隔离级别。

串行化(Serializable)

串行化(Serializable)是最高级别的事务隔离级别,它提供了最强大的数据隔离,确保在事务之间的完全隔离,不会出现脏读、不可重复读、幻读或其他并发问题。让我们详细介绍串行化隔离级别,并提供一个示例来说明其优劣势。

串行化隔离级别的特点

最高隔离程度: 串行化隔离级别确保事务之间的完全隔离,每个事务都仿佛在单独运行,不会看到其他事务的未提交更改。

避免脏读、不可重复读和幻读: 串行化隔离级别彻底避免了脏读、不可重复读和幻读等问题。一个事务在读取数据时,如果另一个事务正在修改相同的数据,它将被阻塞,直到另一个事务完成。

保证一致性: 串行化隔离级别确保数据的一致性,即使在高并发环境下也不会出现数据不一致的情况。

示例

假设有一个银行的数据库,其中包含账户余额的数据。

  1. 用户A正在执行一个转账操作,将100美元从他的账户转移到用户B的账户。

  2. 同时,用户B正在查询他的账户余额。

  3. 在串行化隔离级别下,用户B的查询操作将会被阻塞,直到用户A的事务完成。因为用户A的事务正在修改用户B的账户,数据库会确保不会允许用户B查询到中间状态的余额。

  4. 只有当用户A的事务完成后,用户B的查询操作才会继续执行,此时用户B将看到正确的账户余额。

优势和劣势

优势:

1. 最高隔离: 串行化隔离级别提供了最高级别的隔离,确保事务之间完全独立运行。

2. 数据一致性: 串行化隔离级别确保数据的一致性,不会出现并发问题,即使在高并发环境下也能维护数据的完整性。

劣势:

1. 性能开销: 串行化隔离级别可能导致性能开销较大,因为事务需要等待锁释放,可能会导致事务执行时间延长。

2. 资源争夺: 高并发情况下,事务可能会争夺资源,导致一些事务等待时间过长。

串行化隔离级别适用于那些对数据一致性要求极高的应用,例如金融系统。然而,它的性能开销较大,不适用于所有场景,因此需要谨慎选择隔离级别。

本期就到这里啦,喜欢的友友可以三连支持一下博主噢!🤩

相关推荐
M1A14 分钟前
Java 面试系列第一弹:基础问题大盘点
java·后端·mysql
He.ZaoCha4 分钟前
函数-1-字符串函数
数据库·sql·mysql
二当家的素材网12 分钟前
Centos和麒麟系统如何每天晚上2点10分定时备份达梦数据库
linux·数据库·centos
白仑色19 分钟前
Oracle 存储过程、函数与触发器
数据库·oracle·数据库开发·存储过程·plsql编程
夕颜11125 分钟前
关于 Cursor 小插曲记录
后端
考虑考虑29 分钟前
go中的Map
后端·程序员·go
叁沐39 分钟前
MySQL 09 普通索引和唯一索引,应该怎么选择?
mysql
邓不利东1 小时前
Spring中过滤器和拦截器的区别及具体实现
java·后端·spring
头发那是一根不剩了2 小时前
Spring Boot 多数据源切换:AbstractRoutingDataSource
数据库·spring boot·后端