MySQL四种事务隔离级别

事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。本文对MySQL的四种隔离级别进行了简述,至于锁和隔离级别具体的实现原理会在后续的文章中讲解。

一、MySQL四种隔离级别简述

什么是隔离级别呢?我们都知道,单事务顺序操作数据库时,不论对数据进行什么操作,读到的都应该是数据库中最新的数据。但是大多数系统都不会只在数据库中进行顺序操作,在一个事务A中进行操作时,另一个事务B很可能正在读取同一条数据,那么B应该读取A提交前的数据,还是提交后的数据呢?根据实际业务不同需要,MySQL提供了四种隔离级别供我们选择:

名称 含义
Read Uncommitted 读取未提交内容
Read Committed 读取提交内容
Repeatable Read 可重读
Serializable 可串行化

二、四种隔离级别的区别

准备工作

只需要准备两个MySQL连接终端(简称A、B)和一张account表(在本文中,name字段没有用):

id (pk) name balance
1 X 200

1、Read Uncommitted

两个终端内设置并分别启动事务:

//先设置session为RU:
set session transaction isolation level read uncommitted;
//启动事务:
start transaction;

此时B对数据进行更新:

update account set balance=balance-50 where id=1;

在B没有提交的前提下,我们在A终端内进行查询:

select * from account;

得到数据并与之前对比:

id (pk) name balance(之前) balance(现在) 变化
1 X 200 150 -50

对于A终端来说,B终端即使不提交,数据也可以生效。如果此时我们对终端B进行回退处理:

rollback;

就会在A终端内查询到最初始的数据:

id (pk) name balance
1 X 200

所以对于A终端来说,RU是可以查到最新的未提交的数据(脏数据),这个级别我们一般不用。

2、Read Committed

将balance恢复到200,然后进行设置:

//先设置session为RU:
set session transaction isolation level read committed;
//启动事务:
start transaction;

此时B对数据进行更新:

update account set balance=balance-50 where id=1;

在B没有提交的前提下,我们在A终端内进行查询:

select * from account;

得到数据并与之前对比:

id (pk) name balance(之前) balance(现在) 变化
1 X 200 200

对于A终端来说,B终端不提交,数据就不会生效。如果此时我们对终端B进行提交处理:

commit;

就会在A终端内查询到生效的数据:

id (pk) name balance(之前) balance(现在) 变化
1 X 200 150 -50

所以对于A终端来说,RC是可以查到最新的已提交的数据,但是不可以重复读(虽然A事务本身没有对数据进行操作,但是数据也会发生变化)。如果你要用confluence或一些其他特定的APP的话,会强制要求数据库是RC级别的。

3、Repeatable Read

将balance恢复到200,然后进行设置:

//先设置session为RU:
set session transaction isolation level repeatable read;
//启动事务:
start transaction;

此时B对数据进行更新:

update account set balance=balance-50 where id=1;

在B没有提交的前提下,我们在A终端内进行查询:

select * from account;

得到数据并与之前对比:

id (pk) name balance(之前) balance(现在) 变化
1 X 200 200

对于A终端来说,B终端不提交,数据就不会生效。如果此时我们对终端B进行提交处理:

commit;

A终端内查询到的数据依然与之前一样:

id (pk) name balance(之前) balance(现在) 变化
1 X 200 200

所以对于A终端来说,虽然RR给出的数据不是最新生效的数据,但是这代表同一事务内的数据可以重复读取,这是InnoDB的默认隔离级别。注意别关掉,我们再尝试一些比较有意思的东西:

在A终端内再对数据进行操作,扣掉50块钱:

update account set balance=balance-50 where id=1;

猜猜现在A终端会是多少钱呢?我们设想,A终端查到的是200块钱,那么扣掉50以后,应该是150对不对?然而结果并不是150,而是100:

id (pk) name balance(之前) balance(现在) 变化
1 X 200 100 -100

也就是说,我们读到的不是最新生效的数据,但是update的时候取出来更新的却是最新生效的数据。如果有兴趣的话,还可以试试同时开启事务后,B终端插入一条id为2的数据并提交,此时A终端虽然不能查询到该条数据,但是当A终端也插入一条id为2的数据的时候,会发生主键冲突。这个原因在于select是受到事务隔离级别控制的,读取记录叫做“快照读”,而insert、update、select for update是直接对记录进行加锁,获取最新生效记录(读取结果等于RC,但是要锁行),叫做“当前读”。

4、Serializable

将balance恢复到200,然后进行设置:

//先设置session为RU:
set session transaction isolation level serializable;
//启动事务:
start transaction;

先在A终端内进行查询:

select * from account;

此时B对数据进行更新:

update account set balance=balance-50 where id=1;

发现在A终端提交之前,B终端进入了等待,是不会返回执行结果的,这就是把事务进行了串行化,好比之前是好几个窗口开展业务,现在只有一个窗口开展业务。虽然克服了幻读、脏读的问题,但是性能上受到非常大的影响,因此日常业务中使用的也比较少。

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