[转帖]事务隔离级别

事务,隔离,级别 · 浏览次数 : 0

小编点评

**事务隔离级别** 事务隔离级别是指数据库事务在并发执行时对数据库的更改的隔离程度,它可以分为**4种**: * **READ UNCOMMITTED**:该隔离级别允许其他事务读取已提交的数据库数据,但不允许其他事务写入或更新该数据。 * **READ COMMITTED**:该隔离级别允许其他事务读取已提交的数据库数据,但不能阻止其他事务写入或更新该数据。 * **REPEATABLE READ**:该隔离级别允许其他事务读取已提交的数据库数据,但其他事务读取的顺序必须与提交顺序一致。 * **SERIALIZABLE**:该隔离级别允许其他事务读取已提交的数据库数据,但其他事务的读取操作会被阻塞,直到其他事务提交修改该数据。 **事务隔离级别的作用** 事务隔离级别可以用来解决并发事务场景下脏读、不可重复读、幻读等异常情况。通过控制其他事务对数据库的访问权限,事务隔离级别可以确保并发事务对数据库的并发性,避免脏读、不可重复读、幻读等问题。 **示例** 以下是一些使用不同隔离级别模拟脏读、不可重复读、幻读的示例: * **脏读**:假设有2个事务对同一个订单数据进行修改,其中一个事务修改订单价格,另一个事务删除订单商品。由于没有设置事务隔离级别,其他事务可以读取到订单价格已修改的值。 * **不可重复读**:假设有3个事务对同一个订单数据进行修改,其中2个事务修改订单价格,另一个事务删除订单商品。由于没有设置事务隔离级别,其他事务可以读取到订单价格已修改的值。 * **幻读**:假设有4个事务对同一个订单数据进行修改,其中3个事务修改订单价格,另一个事务删除订单商品。由于没有设置事务隔离级别,其他事务可以读取到订单价格已修改的值。 **总结** 事务隔离级别是解决并发事务场景下脏读、不可重复读、幻读等异常情况的重要方法。不同隔离级别可以根据不同的场景选择,以确保并发性和性能的平衡。

正文

https://www.jianshu.com/p/51035d3f6953

 

本文主要为了总结事务隔离级别的整体知识,包含模拟脏读、不可重复读和幻读的场景

1. 什么是事务隔离级别?

什么是事务?

要了解什么是事务隔离级别,需要先了解什么事务,可参考 百度百科-数据库事务 的概念解释,简单来说:

数据库事务,描述的是对数据库进行读写操作的一个操作序列,要么全部执行,要么全都不执行的现象,这个操作序列是原子性的、不可分割的工作单元

并且数据库事务包含如下 4 个经典特性,也就是常说的 ACID 特性:

  • 原子性(Atomicity)

    事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行

  • 一致性(Consistency)

    几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致

    也就是说,当执行数据库事务操作后(事务提交或者事务回滚),数据库的完整性约束不能被破坏

  • 隔离性(Isolation)

    事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的

  • 持久性(Durability)

    对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障

为什么要有事务隔离级别?

数据库的事务经常需要并发执行,也即经常会有多个客户端连接到数据库上来进行读写操作,并发事务下会发生如下几种问题:

  • 丢失更新,包含回滚丢失和覆盖丢失两种

    可参考:并发事务导致的丢失更新及处理方式详解 博文进行了解

  • 脏读

    某个事务读到了其他事务还没有提交的数据

  • 不可重复读

    着重指针对某一行数据,在同一个事务内多次读取的内容不同,同一条记录的内容被修改了(或删除了)

    产生原因:读取过程中,有其他事务对该数据进行了修改或删除

  • 幻读, 参见 mysql-官网-幻读说明

    着重指在同一个事务里的操作发现了未被操作的数据

    比如,事务 A 根据条件查询得到了 N 条数据,准备进行更新操作;但此时事务 B 新增或删除了 M 条符合事务 A 查询条件的的数据;当事务 A 执行更新操作,重新查询后发现了 M 条自己不应该进行更新的记录,就像发生了幻觉一样

    注意,上述示例的事务 A 的查询得到 N 条数据,准备更新这 N 条数据,并重新根据条件进行查询的操作均在同一个事务内

其中,丢失更新的问题是由于临界资源使用不当造成(同一条数据被并发修改,该条数据应被视为共享临界资源,需要使用者控制好加锁方式),可通过加锁方式来解决

而脏读、不可重复读和幻读,则需要通过事务隔离级别的控制来加以解决,通过不同级别的事务隔离级别,来解决相应的脏读、不可重复读和幻读问题,而事务隔离级别越高,在并发事务场景下会产生的问题就越少,但数据库付出的性能消耗也就越大,并发能力也就越低,因此需要根据不同场景设置不同的事务隔离级别,在事务并发性和数据库性能之间做一个平衡

什么是事务隔离级别?

了解了什么是事务,以及为什么要有事务隔离级别之后,我们再来回答什么是事务隔离级别,就比较轻松了:

在 SQL-92 标准中定义了并发事务场景下脏读、不可重复读和幻读这三种异常情况,而为了解决这些异常情况,SQL-92 标准还定义了 4 种隔离级别来解决这些异常,具体有哪 4 种隔离级别可参照下文

所以简单说,事务隔离级别就是为了解决并发事务场景下脏读、不可重复读和幻读异常而提出的一种应对方式

2. 事务隔离级别有哪些,解决了什么问题?

数据库的事务隔离级别主要有以下 4 种:

  • 读未提交(READ UNCOMMITTED)

    能够读取到其他事务没有提交的数据,不能解决脏读、不可重复读、幻读

  • 读已提交(READ COMMITTED)

    能够读取到其他事务已经提交的数据,可以防止脏读,但不能防止不可重复读和幻读

  • 可重复读(REPEATABLE READ)【MySQL 默认事务隔离级别】

    保证一个事务在相同查询条件下两次查询得到的数据结果是一致的,可以避免不可重复读和脏读,但无法避免幻读

  • 串行化(SERIALIZABLE)

    最高级别的隔离等级,将事务进行串行化,也就是在一个队列中按照顺序执行,可以解决脏读、不可重复读和幻读,但是牺牲了系统的并发性

不同事务隔离级别能解决的异常情况,表格展示如下:

事务隔离级别脏读不可重复读幻读
读未提交(READ UNCOMMITTED) 允许 允许 允许
读已提交(READ COMMITTED) 不允许 允许 允许
可重复读(REPEATABLE READ) 不允许 不允许 允许
串行化(SERIALIZABLE) 不允许 不允许 不允许

3. 事务隔离级别的查看与修改

以 MySQL 引擎为例进行说明

查看 MySQL 引擎事务隔离级别

通过如下 sql 可查看 MySQL 引擎的事务隔离级别:

-- 查询 MySQL 引擎事务隔离级别变量设置,适用于所有版本的 MySQL 引擎查询
SHOW VARIABLES LIKE '%isolation%';

-- 直接查询 MySQL 事务隔离级别变量设置,需明确 MySQL 引擎版本,不同版本的变量设置不一样,可参考下文表格(示例为 5.6 版本)
SELECT @@tx_isolation;

不同版本的 MySQL 引擎(可通过 select version() 查询 MySQL 版本),事务隔离级别变量的设置不一致,以表格形式进行展示:

MySQL 引擎版本事务隔离级别变量
5.6 tx_isolation
5.7 tx_isolation, transaction_isolation
8.0.19 transaction_isolation

修改MySQL 引擎事务隔离级别

事务隔离级别的参数包含如下 4 种:

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

按照修改生效的作用于区分,可分为如下两种修改:

  • 修改当前会话事务隔离级别(当前会话即为当前连接)

    -- 将当前会话的事务隔离级别设置为可重复读,`REPEATABLE READ` 参数可替换成上述 4 种参数的任意一种
    SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    
  • 修改全局事务隔离级别(即对之后的所有连接均生效)

    -- 将全局事务隔离级别设置为可重复读,`REPEATABLE READ` 参数可替换成上述 4 种参数的任意一种
    SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    

4. 使用 MySQL 客户端模拟脏读、不可重复读、幻读

模拟脏读

可参考 廖雪峰-事务-脏读示例演示,示例简单,清晰明了,包含简短视频演示

模拟不可重复读

可参考 廖雪峰-事务-不可重复读示例演示,示例简单,清晰明了,包含简短视频演示

模拟幻读

可参考 廖雪峰-事务-幻读示例演示,示例简单,清晰明了,包含简短视频演示

与[转帖]事务隔离级别相似的内容:

[转帖]事务隔离级别

https://www.jianshu.com/p/51035d3f6953 本文主要为了总结事务隔离级别的整体知识,包含模拟脏读、不可重复读和幻读的场景 1. 什么是事务隔离级别? 什么是事务? 要了解什么是事务隔离级别,需要先了解什么事务,可参考 百度百科-数据库事务 的概念解释,简单来说: 数

[转帖]一文看懂mysql数据库事务隔离级别

概述 我们都知道除了MySQL默认采用RR隔离级别之外,其它几大数据库都是采用RC隔离级别。那为啥mysql要这样设置呢?其实是MySQL为了规避一个数据复制场景中的缺陷,而选择 Repeatable Read 作为默认隔离级别。不过不同数据库实现方式还是不太一样。 Oracle仅仅实现了RC 和

[转帖]mvcc多版本并发控制的原理

https://baijiahao.baidu.com/s?id=1751185558149315946 MVCC多版本并发控制的原理:通过undo_log多版本链条,加上开启事务时产生的readView(不同隔离级别有不同产生策略),然后再有一个查询的时候,根据readView进行判断的机制,来决

[转帖]事务上的等待事件 —— enq: TX - contention

TX锁是保护事务的,事务结束时便会释放。因此,为获得TX锁为等待的会话,要等到拥有锁的会话的事务结束为止。 SQL> select name,parameter1,parameter2,parameter3 from v$event_name where name like '%enq: TX%';

[转帖]事务上的等待事件 —— enq: TM - contention

执行DML期间,为防止对与DML相关的对象进行修改,执行DML的进程必须对该表获得TM锁。若在获得TM锁的过程中发生争用,则等待enq: HW - contention 事件。 SQL> select name,parameter1,parameter2,parameter3 from v$even

[转帖]MySQL事务的开启与提交,autocommit自动提交功能

MySQL事务的开启与提交,autocommit自动提交功能 https://www.cnblogs.com/deverz/p/6547866.html 对于一个MySQL数据库(InnoDB),事务的开启与提交模式无非下面这两种情况:1、若参数autocommit=0,事务则在用户本次对数据进行操

[转帖]KingbaseES 事务总结

目录 1. 什么是事务? 2. 事务的属性-ACID 3. 数据库事务的操作方式 3.1. SET TRANSACTION 3.2. BEGIN 3.3. COMMIT 3.4. ROLLBACK 3.5. SAVEPOINT 3.6. ROLLBACK TO SAVEPOINT 4. 事务的并发控

[转帖]Percolator - 分布式事务的理解与分析

https://zhuanlan.zhihu.com/p/261115166 Percolator - 分布式事务的理解与分析 概述 一个web页面能不能被Google搜索到,取决于它是否被Google抓取并存入了它的倒排索引。Google管理着万亿级别的倒排索引,并且每天都有着几十亿级别的数据更新

[转帖]Percolator分布式事务模型原理与应用

https://zhuanlan.zhihu.com/p/59115828 Percolator 模型 Percolator[1] 是 Google 发表在 OSDI‘2010 上的论文 Large-scale Incremental Processing Using Distributed Tra

[转帖]Percolator 和 TiDB 事务算法

https://cn.pingcap.com/blog/percolator-and-txn 本文先概括的讲一下 Google Percolator 的大致流程。Percolator 是 Google 的上一代分布式事务解决方案,构建在 BigTable 之上,在 Google 内部 用于网页索引更