专栏首页菩提树下的杨过mysql事务隔离级别/脏读/不可重复读/幻读详解

mysql事务隔离级别/脏读/不可重复读/幻读详解

一、四种事务隔离级别

1.1 read uncommitted 读未提交

即:事务A可以读取到事务B已修改但未提交的数据。

除非是文章阅读量,每次+1这种无关痛痒的场景,一般业务系统没有人会使用该事务隔离级别,标准实在太宽松了。

1.2 read committed 读已提交(简称RC)

即:事务A只能读取到事务B修改并已提交的数据。

这个级别相对要严格一些,至少是要等其它事务把变更提交到db,才能读取到,听上去蛮靠谱的。但是有些业务场景,比如会员系统中,如果要在一个事务中,多次读取用户身份,判断是否会员,如果刚开始读取到该用户是会员,做了一些逻辑处理,后面又读到用户不是会员了,这就有点崩溃,不知道如何继续。这种希望同1个事务中,关键数据不管读取多次次,结果都一样,RC级别就不行了。

1.3 repeatable read 可重复读

即:同一个事务中,多次读取某一行记录,始终是一样的值,不管在此期间,其它事务有没有修改过该数据(不论是否提交)。该级别解决了RC不可重复读的问题,但是存在幻读问题(幻读后面会详解)。

1.4 serializable 串行化

即:一个事务在修改其它数据时,如果有其它事务也想改,必须等前面的事务提交或回滚后,才能继续。最严格的级别,但是性能最低,也几乎没人用。

二、脏读/不可重复读/幻读 2.1 脏读

验证:

a. 找一个mysql环境,建一个测试表t_people,就2列 id ,name

b. 开二个mysql终端,连到db上,为方便讲解,这2个终端称为“终端1”、“终端2”,终端1里输入:

set session transaction isolation level read uncommitted;
start transaction;

即:设置当前会话的隔离级别为"读未提交"。

终端2里,输入:

start transaction;
update t_people set name='xxx' where id=1;

然后再回到“终端1”,执行

select id,name from t_people where id=1;

可以看到,读取到了未提交的脏数据 。 终端2里,此时如果执行rollback回滚

终端1里,继续执行

select id,name from t_people where id=1;

可以发现最新结果,已经是回滚后的数据。很显然:如果有脏读问题出现,就更加保证不了“可重复读”。

2.2 不可重复读

将事务隔离级别设置成read committed(即:读已提交),可解决脏读问题,但满足不了“可重复读需求”。

验证方法跟刚才类似,终端1里输入:

set session transaction isolation level read committed;

将级别设置成RC,然后2个终端里都开启事务,终端2中,修改一行数据,但是不提交,此时终端1里应该是读不到终端2修改的数据。然后终端2提交,终端1才能读到修改后的数据。终端2如果继续修改、提交,终端1里再读取这1行,将是最新的值。(也就是只说,只要终端2不断修改,不断提交,终端1里就能读到这行不同的新值,即:保证不了同1个事务中,同一行数据,多次重复读取的值不变)

2.3 幻读

将隔离级别继续调整至Repeatable Read,还是刚才的场景,变成这样:

事务A对于同一行数据,不管读多少次,始终是相同的值,完全不理会有没有其它事务在修改它。有点:“两耳不闻窗外事,一心只读圣贤书”的味道。但是这也有问题,比如秒杀订单系统中,事务A第1次读取商品库存,发现还有1个,可以下单,赶紧继续,但是此时,可能有另一个事务,也在下单,已经提交了订单,把库存减为0了,事务A并不知道,因为多次读取库存的值是一样的,还是1,最后仍然把订单创建了,形成超卖。

验证方法:

set session transaction isolation level repeatable read;

剩下的步骤跟前面类似,就不重复赘述了。 

2.4 串行化

从db层面,要想同时解决脏读、不可重复读、幻读,只有串行化这个级别可以做到。

set session transaction isolation level serializable;

如下图:终端1设置串行化后,紧接着select xxx where id=1这条语句后,id=1的这行记录,就被锁了。

在终端2里,更新其它记录(即:id不等于1)可以正常成功,但是更新id=1 时,就会卡住,除非终端1把事务提交或回滚,否则将一直卡着,直到超时失败。

小结:

隔离级别

存在的问题

读未提交

脏读、不可重复读、幻读

读已提交

不可重复读、幻读

可重复读

幻读

串行化

性能问题

隔离级别越严格,db综合性能越低。

建议:

大多数情况下,RC(读已提交)基本上就足够了,如果并发度高,可以考虑“RC级别+(应用层)分布式锁”,这样即能保证数据正确,对db的性能压力也较低。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ExtJs学习笔记(20)-利用ExtJs的Ajax与服务端WCF交互

    ExtJs是一套非常不错的javascript UI库(第一次接触ExtJs的,可到官方网站http://www.extjs.com/deploy/dev/ex...

    菩提树下的杨过
  • Flash/Flex学习笔记(16):如何做自定义Loading加载其它swf

    const FILE_PATH:String="main.swf"; const CLASS_NAME:String="MainSwf"; var loade...

    菩提树下的杨过
  • C#检测SqlServer中某张表是否存在

    -- ============================================= -- Author: <杨俊明(菩提下的杨过 http://...

    菩提树下的杨过
  • Facebook不让美国,英国和澳大利亚"走后门"

    Facebook在周一拒绝了美国,英国和澳大利亚的要求。要求提出需要一个“后门”功能来通向端到端加密的Messenger应用,以协助执法机构打击犯罪和恐怖主义。

    shellmik
  • 马斯克:生物智能和电子智能的融合将更加紧密,人类应该准备好成为“半机械人”

    【新智元导读】马斯克昨天在WGS峰会上称,在人工智能大行其道的时代,人类将变得毫无用处,所以人类有必要与机器进行融合,变成“半机械人”,否则将被淘汰。而且这还能...

    新智元
  • 马斯克警告:未来数字智能必战胜生物智能,人类要想生存只有“人机合并”

    此前,他曾经在一场访谈中表示,人类极有可能生活在更高文明模拟的矩阵游戏中。近日,马斯克再次强调了他的观点:人类必须与机器结合,否则将被人工智能淘汰。

    新智元
  • 马斯克为何创办Neuralink?背后是硅谷钢铁侠对AI的恐惧

    △ 伊隆·马斯克,特斯拉及OpenAI联合创始人,在SpaceX猎鹰9号火箭部件内部 2010年摄于佛罗里达州 卡纳维拉尔角 王新民 允中 编译整理 量子位 出...

    量子位
  • XSStrike:基于Python的XSS测试工具

    简介 XSStrike 是一款用于探测并利用XSS漏洞的脚本 XSStrike目前所提供的产品特性: 对参数进行模糊测试之后构建合适的payload 使用pay...

    企鹅号小编
  • “打脸”世界杯:AI界没有预测比赛的章鱼保罗

    即便不是足球迷,你也应该听说过章鱼保罗。2010 年南非世界杯,这条八爪鱼预测的比赛结果 8 猜全中,这一不可思议的神奇预测让它受到了全世界球迷的追捧,并赐封其...

    AI科技大本营
  • 科技狂人马斯克的五个大胆预测 你同意其中哪一个?

    腾讯科技讯 1月24日据国外媒体报道,特立独行的亿万富翁、科技狂人企业家埃隆·马斯克一直以来都以进行疯狂大胆的预测著称。 这位特斯拉和SpaceX首席执行官最新...

    企鹅号小编

扫码关注云+社区

领取腾讯云代金券