事务隔离级别

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

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 客户端模拟脏读、不可重复读、幻读

模拟脏读

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

模拟不可重复读

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

模拟幻读

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355