一. 并发场景下的问题

相对于串行处理方式,并发的事务处理可显著提升数据库的事务吞吐量、提高资源利用率。在MySQL实际应用中,根据场景的不同,可以分为以下几类:

  • 读读并发
  • 读写并发
  • 写写并发

在这些场景下,可能会出现更新丢失、脏读、不可重复度、幻读的问题。

  • 更新丢失:当多个事务同时更新某1/n行数据时,最后提交的事务会将之前提交的更新覆盖。
  • 脏读:一个事务正在插入/更新一行数据,在该事务提交之前,这条数据处于“不一致”状态。其他事务读取到这条“脏数据”并据此做进一步处理,就会产生对未提交数据的依赖关系,这种现象称为脏读。
  • 不可重复读:一个事务在查询某条数据的一定时间后再次查询该数据,却发现该条数据已经发生了更新或被删除,这种现象称为不可重复读。
  • 幻读:一个事务以相同的查询条件先后两次查询数据,第二次查询结果出现了第一次查询没有的新数据,这种情况称为幻读。

其中,在各类并发场景下会出现的问题如下:

  • 读读并发场景不会导致数据不一致问题,因此无需特殊处理。
  • 读写并发场景可能会出现脏读、不可重复读、幻读的问题。
  • 写写并发场景可能会出现更新丢失的问题。

二.事务隔离级别

针对上述描述的问题,MySQL采用不同的事务隔离级别分别用于解决上述的部分问题,具体如下:

隔离级别 含义 读数据一致性 更新丢失 脏读 不可重复读 幻读
读未提交(Read Uncommitted) 事务中的修改,即使没有提交,对其他事务依然可见。 最低级别,只能保证不读取物理上损坏的数据。  否  是   是  是 
读已提交(Read Committed) 只有已提交事务所做的修改才对其他事务可见。 语句级  否
可重复读(Repeatable Read ) 同一事务中多次读取相同的记录结果时一致的。 事务级  否
串行化(Serializable) 在读取的每一行数据上加锁,强制事务串行执行,不支持并发。 事务级  否  否 

在上述隔离级别中,从上到下并发性能依次降低,安全性依次提高。InnoDB存储引擎下默认的事务隔离级别是RR,可通过如下SQL查询事务隔离级别。

select @@global.tx_isolation;

三.事务隔离级别的实现

InnoDB对事务隔离级别的实现,基本可分为如下两种或两种的组合:

1.多版本并发控制(MVCC,Multiversion Currency Control)

MVCC可用来解决读写并发场景下的脏读、不可重复读问题。具体在不同隔离级别下的应用如下:

  • RC:可解决脏读问题。
  • RR:可解决脏读、不可重复读问题。

具体实现可参考这里,此处针对链接中的文章做简单补充:

相较于RC,RR之所以能够解决不可重复读问题,原因在于RR隔离级别下读取Read-View是事务级别的,RC是语句级别的。即:RR只在事务开始时读取一次Read-View,因此一个事务中的多次查询依赖同一个Read-View,能实现可重复读。RC级别下每次查询均读取     最新的Read-View,无法保证同一事务中先后读取到的Read-View是相同的,这也是先后读取到的数据有差异的原因。

2.锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据了而言显得尤为重要。

锁可以解决上述描述读写并发场景下的幻读问题、写写并发场景下的更新丢失问题。下面针对锁、锁的类型及其应用场景展开详细描述。

2.1锁的基本原理

http://mysql.taobao.org/monthly/2016/01/01/

https://mp.weixin.qq.com/s/yq5Erdv5Dft3foJEVE2dxA

https://i6448038.github.io/2019/02/23/mysql-lock/

https://www.163.com/dy/article/G0S7FSGG05319WXB.html

duplicate key check检查时需要在二级唯一索引上加gap lock(版本:5.6之前,5.7.26-29之后加record lock)

https://juejin.cn/post/6844903597029720072

https://my.oschina.net/hebaodan/blog/3045246

死锁发生场景:

  • 事务1,2均获取某一行数据的s锁后,均想获取x锁。
  • 事务1,2均获取到某一间隙锁后,希望进行插入操作,即增加插入意向锁。
  • 事务1,2操作同一条数据。由于检索条件不同,事务1,2分别锁定了聚簇索引和二级索引,然后事务1无法操作二级索引(先删除,再插入),事务2无法操作聚簇索引,发生死锁。(参考http://mysql.taobao.org/monthly/2016/01/01/)

透过“锁”事看InnoDB对并发的处理?的更多相关文章

  1. Java并发(九)【转载】不可不说的Java“锁”事

    转载自 美团技术团队,原文链接 不可不说的Java“锁”事 前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率.本文旨在对锁相关源码(本文中的源码来自JDK ...

  2. 你用对锁了吗?浅谈 Java “锁” 事

    每个时代,都不会亏待会学习的人 大家好,我是yes. 本来打算继续写消息队列的东西的,但是最近在带新同事,发现新同事对于锁这方面有一些误解,所以今天就来谈谈"锁"事和 Java 中 ...

  3. InnoDB高并发原理

    一.并发控制 为啥要进行并发控制? 并发的任务对同一个临界资源进行操作,如果不采取措施,可能导致不一致,故必须进行并发控制(Concurrency Control). 技术上,通常如何进行并发控制? ...

  4. Netty的那些”锁”事

    Netty锁事的五个关键点: ① 在意锁的对象和范围  --> 减少粒度 ②  注意锁的对象本身大小   --> 减少空间占用 ③ 注意锁的速度 --> 提高速度 ④不同场景选择不同 ...

  5. MySQL锁:02.InnoDB锁

    目录 InnoDB锁 InnoDB行锁实现机制 InnoDB隐式.显式锁 InnoDB锁类型 共享锁 排他锁 意向锁 InnoDB锁兼容性 InnoDB行锁范围.粒度 InnoDB行锁粒度一览 意向插 ...

  6. MySQL锁:03.InnoDB行锁

    目录 InnoDB 行锁 锁排查可以用的视图和数据字典 InnoDB 行锁兼容性 InnoDB行锁之共享锁 共享锁: 查看InnoDB锁 InnoDB行锁实现机制 对普通索引上锁 InnoDB隐式.显 ...

  7. 怎么看innodb的B+TREE层数?

    怎么看innodb的B+TREE层数?,下面以sysbench_testdata.sbtest2为例查看索引层数: - 查看相关系统 root@localhost [sysbench_testdata ...

  8. [转]透过 Linux 内核看无锁编程

    非阻塞型同步 (Non-blocking Synchronization) 简介 如何正确有效的保护共享数据是编写并行程序必须面临的一个难题,通常的手段就是同步.同步可分为阻塞型同步(Blocking ...

  9. MySQL MyISAM/InnoDB高并发优化经验

    最近做的一个应用,功能要求非常简单,就是 key/value 形式的存储,简单的 INSERT/SELECT,没有任何复杂查询,唯一的问题是量非常大,如果目前投入使用,初期的单表 insert 频率约 ...

随机推荐

  1. async await Task 使用方法

    使用概述 C#的使用过程中,除了以前的Thread.ThreadPool等用来开一个线程用来处理异步的内容.还可以使用新特性来处理异步.比以前的Thread和AutoResetEvent.delege ...

  2. Java进阶专题(二十七) 将近2万字的Dubbo原理解析,彻底搞懂dubbo (下)

    ...接上文 服务发现 服务发现流程 整体duubo的服务消费原理 Dubbo 框架做服务消费也分为两大部分 , 第一步通过持有远程服务实例生成Invoker,这个Invoker 在客户端是核心的远程 ...

  3. Androi Studio 之 RelativeLayout

    RelativeLayout简介 •基本属性 •根据父容器定位 •父容器定位属性示意图 •根据兄弟组件定位 •根据兄弟组件定位 •margin(偏移) •padding(填充) •margin与pad ...

  4. CodeForces571A. Lengthening Sticks(组合数学-容斥)

    题目大意: a,b,c三根木棍可以增加三个不同的数字,aa,bb,cc,且aa+bb+cc<=L,问能构成三角形的木棒有多少种方案 题目思路: 如果我们直接考虑把L分配给aa,bb,cc好像不好 ...

  5. Python常用时间转换

    1 import time 2 import math 3 4 # 定义一些时间段的常量(秒) 5 TimeSec_Hour = 3600 6 TimeSec_Day = 86400 7 TimeSe ...

  6. html5 video/audio 标签

    一般来说推荐使用,第三方的媒体播放库[例如 videojs 等],这些库的ui界面,js控制都已写好,功能也扩展的比较丰富 ,直接参考文档使用更加的高效! 这里还是 记录一下 html 原生 vide ...

  7. centos7.4 卸载python2.7.5安装python3.6.3版本

    CentOS 中默认安装了 2.7的Python,为了使用新版 python,可以对旧版本进行升级.但是由于很多基本的命令.软件包都依赖旧版本,比如:yum等.所以,在更新 Python 时,建议不要 ...

  8. baystack(ret2one_gadget)

    babystack 首先检查一下保护 全保护开启,我们IDA分析一下. main函数很简单,首先第一个read明显存在漏洞,如果不是以 \n 结尾会存在栈中地址的泄漏. payload = 'A'*0 ...

  9. Go-23-接口

    接口定义 type 接口名 interface{ 方法1(参数列表) [返回值] 方法2(参数列表)[返回值] } 接口实现 func (变量 结构体类型)方法1 ([参数列表])(返回值){ } f ...

  10. Day05_26_Overide_方法重写

    Overide_方法重写 * 什么是方法重写(Overide)? - 方法重写也叫方法覆盖 ,重写是指子类对父类所允许访问的方法的实现过程进行重新编写, 返回值类型和形参都不能改变.即外壳不变,核心重 ...