18.事务的隔离级别

ANSI SQL标准定义的四个隔离级别分别为:

  • READ UNCOMMITTED 读未提交:就是不同事务之间可以对数据是完全相互可见的,事务B可以见到事务A对某张表做的任何操作,在这种隔离性下的安全性非常低。
  • READ COMMITTED 读已提交:事务A只能看到事务B提交后的操作。这种隔离级别下的安全性相比前者好一点。
  • REPEATABLE READ 可重复读:目前MySQL InnoDB默认的事务隔离级别,在MySQL中已经完全具备ACID特性。
  • SERIALIZABLE 串行化:安全级别最大,但性能上会有损失,由于可重复读已经达到3°隔离,所以本地事务一般不用这个隔离级别,串行化的隔离级别主要用于innoDB的分布式事务中。

1.不同事务隔离级别对锁的支持

1)读未提交(脏读):查询数据时不加锁,更新数据也不加锁,正因为这样,其他事务之间才能做到读未提交。

2)读已提交(不可重复读):在读已提交隔离级别下,除了唯一性的约束检查以及外键约束的检查需要Gap Lock(间隙锁),其他情况下InnoDB存储引擎不会使用Gap Lock锁。

3)可重复读:查询数据时,使用Next-key Lock锁避免幻读情况。

4)串行化:在串行化的隔离级别下,InnoDB会对每个查询语句后自动加上 LOCK IN SHARE MODE(共享锁)。

2.不同事务隔离级别的优缺点

1)读未提交(脏读)
优点:暂时没有
缺点:由于事务中的修改对其他事务都是可见的,所以事务可以读取未提交的数据,如果那些未提交的数据最后回滚了,那么读到的数据就是脏数据,这会导致很多问题。

2)读已提交
优点:相比于读未提交,它防止了脏读
缺点:虽然防止了脏读,但是,它无法避免一致性冲突问题,由于在读已提交隔离性下,一个事务开始时,只能看见已经提交的事务所做的修改
所以同一个事务执行两次相同的查询时会发生两次查询的结果不一致的情况。

3)可重复读
优点:防止脏读,一致性冲突问题
缺点:虽然防止了一致性冲突,但是它无法防止下面的情况:同一个事务中第一次查询时,符合条件的数据有2条,过了一段时间,其他事务插入了一条相同查询条件的数据并提交了,
那么当再次查询时,会查到三条数据,这显然是不对的(幻读)。
注意:但MySQL的InnoDB存储引擎通过MVCC防止了幻读的产生,所以在MySQL中,可重复读已经完全具备ACID特性。

4)串行化
优点:最高的事务隔离级别,安全性最高
缺点:串行化下的事务会在读取的每一行数据上都加锁,这会导致开销相比前面而言增大了许多。

下面的图可帮助理解(但和MySQL的隔离界别有一点差别的):
在这里插入图片描述

3.相关操作语句

1)在InnoDB存储引擎中,可以使用下面命令来设置当前会话或全局的事务隔离级别:

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL
READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE
  1. 查询数据库当前的事务隔离级别
SELECT @@tx_isolation \G;//查看当前会话隔离级别
SELECT @@global.tx_isolation \G;//查看全局事务隔离级别

4.上面提到的锁的知识

1)间隙锁
简单来说过,间隙锁其实就是对范围内的数据进行加锁来防止出现幻读的情况。

2)Next-key Lock锁
他其实是间隙锁和行级锁的合称,它对应两种情况:
当进行范围查询时,使用间隙锁进行锁定范围数据。
当进行索引等值查询时,使用行级锁锁定数据。

おすすめ

転載: blog.csdn.net/c1776167012/article/details/121437686