MySQL事务——事务隔离界别,MVCC
目录
- MySQL事务
- 事务隔离级别
- 事务的特性
- 并发事务引发的问题
- 事务的隔离级别
- Read View在MVCC中的工作过程
- 可重复读的工作过程
- 读提交的工作过程
- 幻读的解决
MySQL事务
事务能够保证一系列操作要么都生效,要么都不生效.
事务隔离级别
事务的特性
原子性:一个事务中的所有操作,要么全部完成,要不一个都不完成
一致性:事务操作前和后,数据满足完整性约束.不会凭空多出来一个数据或少一个数据.
持久性:事务中的操作对数据的影响是持久的,不会随着断电而失效
隔离性:数据库允许多个事务并发执行,隔离性可以防止事务并发执行导致数据的不一致现象发生
InnoDB引擎保证事务特性的方式
持久性——redo log(重做日志)
原子性——undo log(回滚日志)
隔离性——MVCC(多版本并发控制)或锁机制
一致性——持久性+原子性+隔离性
并发事务引发的问题
脏读:一个事务读到了另一个未提交事务修改过程中的数据.
例如:数据a=100,事务A将数据a修改为了200,事务B读取了事务A修改后的结果.事务A发生了回滚
不可重复读:一个事务内多次读取同一个数据,发现前后读取的内容不一致
例如:数据a=100,事务A读取了a的值为100,事务B修改a的值为200并提交事务.事务A再次读取a的值为200,前后两次读取到的结果不同
幻读:一个事务内多次查询某个条件下的记录数量,前后查询到的数量不一致.
事务的隔离级别
- 读未提交(read uncommitted):一个事务还没提交时,它做的变更可以被其他事务读取到
- 读已提交(read committed):一个事务提交之后,它做的变更才可以被其他事务读取到
- 可重复读(repeatable read):一个事务执行过程中看到的数据,和该事务启动时看到的数据保持一致.MySQL InnoDB默认的隔离级别是repeatable read
- 串行化(serializable):会对记录加上读写锁,同一时刻只能有一个事务对记录进行读写操作(将并发执行变成单例执行)
读未提交 | 读已提交 | 可重复读 | 串行化 | |
---|---|---|---|---|
脏读 | × | √ | √ | √ |
不可重复读 | × | × | √ | √ |
幻读 | × | × | × | √ |
在解决幻读时,一般不是将隔离级别设置成串行化,因为那样执行效率过低.而是在可重复读隔离级别下通过next-key lock锁(行锁和间隙锁的组合)来锁住记录之间的间隙和记录本身,防止其他事务在这个记录之间插入新的记录
隔离级别的实现方式
读已提交和可重复读都是通过Read View来实现的.只是实现时机不同.读已提交是在执行每个语句之前重新生成一个Read View,而可重复读是在启动事务时生成一个Read View,然后整个事务期间都用这个Read View
启动事务并不完全等同于开启事务
开启事务有两种命令
- begin/start transaction:开启事务并不是启动事务,只有在执行CRUD时才会启动事务
- begin transaction with consistent snapshot:直接启动事务
串行化:给数据加读写锁
Read View在MVCC中的工作过程
- Read View的四个字段
creator_trx_id:创建该Read View的事务的事务id
m_ids:在创建Read View时,当前数据库中活跃且未提交的事务id列表.活跃指的是启动了但没有提交的事务.
min_trx_id:m_ids的最小值,也就是当前活跃的id最小的事务.
max_trx_id:创建Read View时当前数据库应该给下一个事务的id值,也就是m_ids的最大值+1
主键索引中两个隐藏列
trx_id
当一个事务对某条主键索引记录进行修改时,会将该事务的id存储到trx_id中
trx_id可以分成三部分:已提交事务,已启动但未提交的事务,未启动的事务
事务可见性分析:
首先事务本身对数据的修改是可见的
当修改记录的事务id小于min_trx_id时,说明事务是在创建Read View之前就提交的,所以对当前事务是可见的
当修改记录的事务id在[min_trx_id,max_trx_id)范围内时,需要判断该事务id是否在m_ids中
如果在m_ids中,说明修改记录的事务还没有提交,所以对当前事务不可见
如果不在m_ids中,说明修改记录的事务已经被提交,所以对当前事务可见
当修改记录的事务id大于等于max_trx_id时,说明修改记录的事务还没有生成,所以对当前事务不可见
roll_pointer
当某条主键索引记录发生改变时,原来的记录会被写入到undo日志中,roll_pointer是一个指针,会指向undo日志中的每一个旧版本记录.
可重复读的工作过程
可重复读是在事务启动时创建Read View,在整个事务期间都用一个Read View.
可重复读的工作过程:
假设数据库中有一条数据a[value:100,trx_id:20]
事务A启动[creator_trx_id:21,m_ids:21,min_trx_id:21,max_trx_id:22]
事务B启动[creator_trx_id:22,m_ids:21,22,min_trx_id:21,max_trx_id:23]
事务B首先读取数据a的值,发现a的trx_id小于min_trx_id,所以直接读取a的值为100.
然后事务A修改数据a的值为200,此时a的trx_id变为21,并将旧版本的数据存储到undo log中,事务B再次读取数据a时发现trx_id=min_trx_id,而且a的trx_id在事务B的m_ids中,所以不读取该版本的a,而是依靠roll_pointer读取undo日志中的旧版本的数据a,当校验了旧版本的数据a的trx_id满足要求时,读取该a的值为100.
事务A提交事务,事务B再次读取a的值时,和之前一样,会读取undo log中a的值,所以还是100
读提交的工作过程
读提交是在每次读取数据时创建1个Read View
与可重复读的例子一样
假设数据库中有一条数据a[value:100,trx_id:20]
事务A启动[creator_trx_id:21,m_ids:21,min_trx_id:21,max_trx_id:22]
事务B启动[creator_trx_id:22,m_ids:21,22,min_trx_id:21,max_trx_id:23]
事务B首先读取数据a的值,发现a的trx_id小于min_trx_id,所以直接读取a的值为100.
然后事务A修改数据a的值为200,此时a的trx_id变为21,并将旧版本的数据存储到undo log中,事务B再次读取数据a时会创建一个新的Read View[reator_trx_id:22,m_ids:21,22,min_trx_id:21,max_trx_id:23],然后读取时发现trx_id=min_trx_id,而且a的trx_id在事务B的m_ids中,所以不读取该版本的a,而是依靠roll_pointer读取undo日志中的旧版本的数据a,当校验了旧版本的数据a的trx_id满足要求时,读取该a的值为100.
幻读的解决
首先幻读是基于当前读的前提下才会出现的一种问题.如果只是普通的select查询,那么在可重复读的隔离级别下,读取属于[快照读],读取到的数据都是一致的,不会出现幻读问题.
只有是当前读才会出现幻读,当前读比如说在对数据进行更新之前一定要拿到表中的最新数据或者select…for update(当前读)
InnoDB为了解决可重复读级别下基于当前读引发的幻读的问题,引出了next-key锁,即记录锁和间隙锁的组合.
记录锁:锁的是记录本身
间隙锁:锁的是两个值之间的空隙,防止其他事务在这个空隙间插入新的数据,从而避免幻读
当事务想要插入某条数据到表中时会因为间隙锁而阻塞,当事务想要删除某条数据或更新某条数据时会因为记录锁阻塞
MySQL事务——事务隔离界别,MVCC相关推荐
- [高性能MySQL]-事务与隔离界别
本文主要包括一下内容: (1) 事务的概念与ACID (2)事务的隔离级别 (3)MySQL中的事务 1. 事务与ACID 理解事务是其它高级概念的基础. 事务:事务就是一组原子性的SQL查询,或则说 ...
- MySQL事务的四种隔离界别以及会造成的问题和解决办法
MySQL事务的特性:原子性.隔离性.持久性.一致性 MySQL四种隔离界别:读未提交.读已提交.可重复度.串行化 一.读未提交(read uncommitted): 读未提交:那个问题都不能解决.容 ...
- MySQL之 事务和MVCC
文章目录 事务 What?Why? 事务的四大特性 事务并发存在的问题 事务的隔离级别 MVCC 隐藏字段 undo log 版本链 快照读和当前读 Read View Read Committed ...
- mysql隔离级别加锁情况_MySQL数据库事务各隔离级别加锁情况--read committed amp;amp; MVCC...
上节回顾 上篇记录了我对MySQL 事务 隔离级别read uncommitted的理解. 这篇记录我对 MySQL 事务隔离级别 read committed & MVCC 的理解. 前言 ...
- mysql 默认事务隔离级别_一文读懂MySQL的事务隔离级别及MVCC机制
回顾前文: <一文学会MySQL的explain工具> <一文读懂MySQL的索引结构及查询优化> (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论 ...
- mysql重复读导致余额不对_我所理解的MySQL之四:事务、隔离级别及MVCC
mysql教程栏目介绍MySQL相关的事务.隔离级别及MVCC. MySQL 系列的第四篇,主要内容是事务,包括事务 ACID 特性,隔离级别,脏读.不可重复读.幻读的理解以及多版本并发控制(MVCC ...
- mysql 事物隔离界别_MySQL锁与事务隔离级别
------------恢复内容开始------------ 一.概述 1.锁的定义 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除了传统的计算资源(如CPU.RAM.IO等)的 ...
- 从根儿上理解MySQL | 事务的隔离级别与MVCC
目录 事务简介 事务的概念 MySQL中事务的语法 事务的隔离级别 事务并发执行遇到的问题 MySQL中支持的四种隔离级别 MVCC原理 版本链 ReadView MVCC小结 事务简介 事务的概念 ...
- mysql 事务隔离界别_mysql/mariadb知识点总结(21):事务隔离级别 (事务总结之三)...
这篇文章将会总结mysql中innodb的事务隔离级别,以及幻读.脏读.不可重读的区别. 之前的文章已经总结了事务的相关概念以及事务控制语句,如需参考可点击下列直达链接. 在本博客中,"my ...
最新文章
- linux-swappiness参数的作用及设置
- java源码分析之ArrayList
- 决定系数R2真的可靠吗?
- 我们:待别日相见时,我们都已有所成。挥手向2021告别吧,追求梦想的路上,永远不孤独「2021 年终总结 」
- 【记录】vmware fusion 7 windows 10 unidentified network
- 装饰者模式和适配器模式对比
- Maven的pom.xml文件详解------Build Settings
- 不选择互联网行业,学弟学妹可以选择这些新兴科技行业发展!
- 帆软报表重要Activator之DesignerStartup中的GlobalListenerProvider扩展开发
- AgreementMaker:Efficient Matching for Large Real-World 翻译
- 【运维技术】数据库主从同步搭建
- ENVI入门系列教程---一、数据预处理---4.1 遥感图像正射校正
- testlink xml转excel
- 【pygame】微信飞机大战
- Java 发送邮件工具类(多个收件人,多个抄送人)
- 优点三维逆向建模——消除实景三维应用后顾之忧
- 【数学】GPS经纬度坐标转换
- 软件工程专业职业规划发展路线
- 联想T420S 黑苹果GPT+UEFI单系统安装
- 大数据开发有哪些难点?
热门文章
- python 如何计算平方、次方?平方根、方根?(math.pow()、math.sqrt())
- Java多级动态导出表格,优化版
- [转]IT人的学习方法
- 【Linux】ARM篇一--计算机基础与RAM处理器概论
- 程序员只能吃青春饭?3条晋升之路帮你摆脱程序员中年魔咒!
- 磷酸除杂回用去除铁、铝、氟
- python程序怎么运行-Python如何运行程序
- 2019年大学计算机排名,2019年USNews大学计算机专业排名!
- 读取Excel表格内容转为Sql when then语句
- Qt Creator禁用警告