MySQL事务隔离级别详解(全网最详细)

目录

一,简介

二,查看隔离级别

三,四种隔离级别

SERIALIZABLE(可串行化):

REPEATABLE-READ(可重复读) :

READ-COMMITTED(读取已提交) :

READ-UNCOMMITTED(读取未提交) :

四,如何理解四种隔离级别与脏读,幻读,不可重复读的关系

脏读

不可重复读

幻读

五,浅谈隔离级别的特性所产生的问题


一,简介

在关系型数据库中,事务隔离级别是指多个并发事务之间的隔离程度

MySQL 中事务的隔离级别一共分为四种,分别如下

  • READ-UNCOMMITTED(读取未提交) : 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
  • READ-COMMITTED(读取已提交) : 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
  • REPEATABLE-READ(可重复读) : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • SERIALIZABLE(可串行化) : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

二,查看隔离级别

MySQL8 之前使用如下命令查看 MySQL 隔离级别

//查看默认的全局隔离级别和当前 session 的隔离级别
SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

MySQL8 开始,通过如下命令查看 MySQL 默认隔离级别

//就是关键字变了,由简写变成全写,其他都一样
SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

更改当前隔离级别:

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

四种隔离级别

SERIALIZABLE(可串行化):

        在SERIALIZABLE隔离级别下,事务将被视为完全串行化,因此每个事务都必须按顺序执行,就像是一个接一个地运行一样。这意味着每个事务都可以看到其他已经提交的事务所做的更改,但不会看到其他正在进行的或未提交的事务所做的更改。

        SERIALIZABLE隔离级别可以防止一些常见的并发问题,如脏读、不可重复读和幻读。它确保在任何给定时间点只有一个事务可以访问特定数据,从而保证了数据的一致性和正确性。但是,这种隔离级别也会带来一些性能问题,因为它会导致更多的锁定和更严格的并发控制。因此,应该谨慎使用SERIALIZABLE隔离级别,并在必要时考虑使用较低级别的隔离级别。

REPEATABLE-READ(可重复读) :

        REPEATABLE-READ是一种常见的事务隔离级别,它比READ COMMITTED隔离级别提供了更高的隔离程度,但不如SERIALIZABLE隔离级别严格。

        在REPEATABLE-READ隔离级别下,事务在读取数据时会锁定所涉及的所有数据,以确保其他事务无法修改它们。这样可以防止脏读和不可重复读,因为其他事务无法在当前事务读取数据的同时修改它们。但是,REPEATABLE-READ隔离级别无法防止幻读,因为其他事务仍然可以插入新数据或删除现有数据。

        与READ COMMITTED隔离级别不同,REPEATABLE-READ隔离级别保证在同一事务中重复读取相同数据将会得到相同的结果。也就是说,在同一事务中,任何查询都将看到第一次查询时的相同数据快照,即使其他事务已经对这些数据进行了修改或删除。这种重复读的能力在某些应用程序中是非常重要的,因此REPEATABLE-READ是一种非常流行的事务隔离级别。

        需要注意的是,REPEATABLE-READ隔离级别也会带来一些性能问题,因为它会导致更多的锁定和更严格的并发控制。因此,应该根据应用程序的需求和性能要求来选择最适合的事务隔离级别。

READ-COMMITTED(读取已提交) :

        READ-COMMITTED是一种常见的事务隔离级别,它提供了比READ-UNCOMMITTED更高的隔离程度。在READ-COMMITTED隔离级别下,事务在读取数据时只会锁定正在被其他事务修改的数据,而不是锁定所有涉及的数据

        这样可以避免脏读,因为其他事务无法在当前事务读取数据的同时修改它们。但是,在READ-COMMITTED隔离级别下,其他事务可以在当前事务读取数据的同时提交修改,导致不可重复读,即同一个事务中的两次查询得到的结果不一致。

        需要注意的是,READ-COMMITTED隔离级别不会防止幻读,因为其他事务仍然可以插入新数据或删除现有数据。因此,如果幻读是一个问题,则应考虑使用更高级别的事务隔离级别,如REPEATABLE-READ或SERIALIZABLE。

        READ-COMMITTED隔离级别是一种比较常见的隔离级别,可以在绝大多数应用场景中使用。但是,需要注意的是,它仍然会带来一些性能问题,因为它会导致更多的锁定和并发控制。因此,在选择事务隔离级别时,需要权衡数据的一致性和性能要求。

READ-UNCOMMITTED(读取未提交) :

        READ-UNCOMMITTED是一种最低级别的事务隔离级别,也是最不严格的一种隔离级别。在READ-UNCOMMITTED隔离级别下,事务可以读取其他事务尚未提交的数据,即脏读(dirty read)。

        这种隔离级别的优点是可以提高并发性能,因为它不会在读取数据时对它们进行任何锁定或并发控制。但是,这种隔离级别的缺点是可能会导致数据的不一致性,因为读取的数据可能包含未提交或已回滚的更改,因此不建议在生产环境中使用。

        需要注意的是,大多数关系型数据库默认的事务隔离级别是READ-COMMITTED,而非READ-UNCOMMITTED。因此,如果需要使用READ-UNCOMMITTED隔离级别,通常需要显式地将隔离级别设置为该级别。

        总之,READ-UNCOMMITTED是一种非常不严格的事务隔离级别,应该谨慎使用,并且只在某些特定情况下考虑使用,例如对于只读取数据的报表查询等场景。

四,如何理解四种隔离级别与脏读,幻读,不可重复读的关系

        笔者为何在这里才提到脏读,幻读,不可重复读,是因为我认为这些问题其实与不同隔离级别的特性密不可分,如果抛弃原理谈问题,其实理解是比较晦涩的,在关系型数据库中,事务隔离级别是指多个并发事务之间的隔离程度

        我先简单介绍一下并发事务存在的三种问题,这些问题都是因为并发访问数据库而导致的,因此在设计数据库应用程序时需要考虑并发控制事务隔离,以确保数据的一致性和可靠性。关系型数据库通过提供不同的事务隔离级别来解决这些问题。不同的隔离级别提供了不同的并发控制机制,从而能够在数据的一致性和并发性之间进行权衡

脏读

        脏读(Dirty Read)是指一个事务读取了另一个事务尚未提交的数据。在这种情况下,如果另一个事务回滚,则第一个事务读取到的数据实际上是无效的或错误的。脏读通常会导致数据不一致,因此需要通过事务隔离来防止。

不可重复读

        不可重复读(Non-repeatable Read)是指一个事务在读取某个数据行时,另一个事务修改了该数据行,导致第一个事务两次读取的结果不一致。不可重复读通常发生在一个事务多次读取同一数据时,而其他事务同时修改了该数据。因此,需要通过事务隔离来防止。

幻读

        幻读(Phantom Read)是指一个事务在两次执行同一查询时,第二次查询发现了第一次查询没有发现的新数据行或者第一次查询发现了一些数据行,但是在事务提交前这些数据行被另一个事务删除了。这种现象通常发生在多行数据的插入、更新和删除操作中,它会导致数据不一致,因此需要通过事务隔离来防止。

五,浅谈隔离级别的特性所产生的问题

        在READ-UNCOMMITTED隔离级别下,事务可以读取其他事务尚未提交的数据,所以会产生脏读问题,这是因为READ-UNCOMMITTED的特性导致的,当然也会存在不可重复读和幻读。

        在READ-COMMITTED隔离级别下,事务在读取数据时只会锁定正在被其他事务修改的数据,而不是锁定所有涉及的数据。这样可以避免脏读,因为其他事务无法在当前事务读取数据的同时修改它们,但是因为可以读到其他事务提交的数据,所以在其他事务提交前后,分别读,就会产生不可重复读的问题。

        在REPEATABLE-READ隔离级别下,会保证在同一事务重复读取相同数据将会得到相同的结果。也就是说,在同一事务中,任何查询都将看到第一次查询时的相同数据快照,即使其他事务已经对这些数据进行了修改。以插入数据(数据比如叫做小尹)举例,这就会导致,虽然你在A事务查询的时候,数据库中没有小尹的数据,但是B事务此时修改了小尹的数据并且提交,此时A事务哪怕查询不到小尹的数据,但是插入时,依然会报错。这就是幻读。

        在SERIALIZABLE隔离级别下,事务将被视为完全串行化,因此每个事务都必须按顺序执行,就像是一个接一个地运行一样,自然并发条件下的问题就不会出现。

  • 13
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL事务隔离级别决定了在并发环境下多个事务之间的隔离程度。MySQL提供了四个事务隔离级别,分别是读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。以下是对这四个隔离级别详细解释: 1. 读未提交(Read Uncommitted):这是最低级别的隔离级别。在该级别下,一个事务可以看到其他事务未提交的修改。这可能导致脏读(Dirty Read)和不可重复读(Non Repeatable Read)的问题。 2. 读已提交(Read Committed):在该级别下,一个事务只能看到其他事务已经提交的修改。这可以避免脏读的问题,但仍可能导致不可重复读的问题。 3. 可重复读(Repeatable Read):在该级别下,一个事务在执行期间能够看到同一结果集的一致性快照。这可以避免脏读和不可重复读的问题,但仍可能导致幻读(Phantom Read)的问题。 4. 串行化(Serializable):在该级别下,事务之间是完全隔离的,每个事务必须按照顺序执行。这可以避免脏读、不可重复读和幻读的问题,但也会导致并发性能的严重下降。 要查看MySQL的默认隔离级别和当前会话的隔离级别,可以使用以下命令: ```sql SELECT @@GLOBAL.tx_isolation, @@tx_isolation; ``` 请注意,MySQL 8之前可以使用上述命令,而MySQL 8及更高版本可以使用以下命令: ```sql SELECT @@global.transaction_isolation, @@transaction_isolation; ``` 这样可以查看默认的全局隔离级别和当前会话的隔离级别。这些隔离级别可以通过设置`transaction_isolation`参数来进行更改。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值