彻底搞懂 MySQL 事务的隔离级别
本文系转载,方便自己整理和查看相应文章,原文地址 https://developer.aliyun.com/article/743691
事前准备数据
mysql> create table city(-> id int(10) auto_increment,-> name varchar(30),-> primary key (id)-> )engine=innodb charset=utf8mb4;insert into city(name) values('武汉市');mysql> select * from city;
+----+-----------+
| id | name |
+----+-----------+
| 1 | 武汉市 |
+----+-----------+
事务并发可能出现的情况
脏读(Dirty Read)
一个事务读到了另一个未提交事务修改过的数据
会话B开启一个事务,把id=1的name为武汉市修改成温州市,此时另外一个会话A也开启一个事务,读取id=1的name,此时的查询结果为温州市,会话B的事务最后回滚了刚才修改的记录,这样会话A读到的数据是不存在的,这个现象就是脏读。(脏读只在读未提交隔离级别才会出现)
不可重复读(Non-Repeatable Read)
一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。(不可重复读在读未提交和读已提交隔离级别都可能会出现)
会话A开启一个事务,查询id=1的结果,此时查询的结果name为武汉市。接着会话B把id=1的name修改为温州市(隐式事务,因为此时的autocommit为1,每条SQL语句执行完自动提交),此时会话A的事务再一次查询id=1的结果,读取的结果name为温州市。会话B再此修改id=1的name为杭州市,会话A的事务再次查询id=1,结果name的值为杭州市,这种现象就是不可重复读。
幻读(Phantom)
一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。(幻读在读未提交、读已提交、可重复读隔离级别都可能会出现)
会话A开启一个事务,查询id>0的记录,此时会查到name=武汉市的记录。接着会话B插入一条name=温州市的数据(隐式事务,因为此时的autocommit为1,每条SQL语句执行完自动提交),这时会话A的事务再以刚才的查询条件(id>0)再一次查询,此时会出现两条记录(name为武汉市和温州市的记录),这种现象就是幻读。
事务的隔离级别
MySQL的事务隔离级别一共有四个,分别是读未提交、读已提交、可重复读以及可串行化。
MySQL的隔离级别的作用就是让事务之间互相隔离,互不影响,这样可以保证事务的一致性。
隔离级别比较:可串行化>可重复读>读已提交>读未提交
隔离级别对性能的影响比较:可串行化>可重复读>读已提交>读未提交
由此看出,隔离级别越高,所需要消耗的MySQL性能越大(如事务并发严重性),为了平衡二者,一般建议设置的隔离级别为可重复读,MySQL默认的隔离级别也是可重复读。
读未提交(READ UNCOMMITTED)
在读未提交隔离级别下,事务A可以读取到事务B修改过但未提交的数据。
可能发生脏读、不可重复读和幻读问题,一般很少使用此隔离级别。
读已提交(READ COMMITTED)
在读已提交隔离级别下,事务B只能在事务A修改过并且已提交后才能读取到事务B修改的数据。
读已提交隔离级别解决了脏读的问题,但可能发生不可重复读和幻读问题,一般很少使用此隔离级别。
可重复读(REPEATABLE READ)
在可重复读隔离级别下,事务B只能在事务A修改过数据并提交后,自己也提交事务后,才能读取到事务B修改的数据。
可重复读隔离级别解决了脏读和不可重复读的问题,但可能发生幻读问题。
提问:为什么上了写锁(写操作),别的事务还可以读操作?
因为InnoDB有MVCC机制(多版本并发控制),可以使用快照读,而不会被阻塞。
可串行化(SERIALIZABLE)
各种问题(脏读、不可重复读、幻读)都不会发生,通过加锁实现(读锁和写锁)。
隔离级别的实现原理
使用MySQL的默认隔离级别(可重复读)来进行说明。
每条记录在更新的时候都会同时记录一条回滚操作(回滚操作日志undo log)。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)。即通过回滚(rollback操作),可以回到前一个状态的值。
假设一个值从 1 被按顺序改成了 2、3、4,在回滚日志里面就会有类似下面的记录。
当前值是 4,但是在查询这条记录的时候,不同时刻启动的事务会有不同的 read-view。如图中看到的,在视图 A、B、C 里面,这一个记录的值分别是 1、2、4,同一条记录在系统中可以存在多个版本,就是数据库的多版本并发控制(MVCC)。对于 read-view A,要得到 1,就必须将当前值依次执行图中所有的回滚操作得到。
同时你会发现,即使现在有另外一个事务正在将 4 改成 5,这个事务跟 read-view A、B、C 对应的事务是不会冲突的。
提问:回滚操作日志(undo log)什么时候删除?
MySQL会判断当没有事务需要用到这些回滚日志的时候,回滚日志会被删除。
提问:什么时候不需要了?
当系统里么有比这个回滚日志更早的read-view的时候。
查看当前会话隔离级别
方式1
命令:SHOW VARIABLES LIKE 'transaction_isolation';mysql> show variables like 'transaction_isolation';
+-----------------------+--------------+
| Variable_name | Value |
+-----------------------+--------------+
| transaction_isolation | SERIALIZABLE |
+-----------------------+--------------+
方式2
命令:SELECT @@transaction_isolation;mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| SERIALIZABLE |
+-------------------------+
设置隔离级别
方式1:通过set命令
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level;
其中level有4种值:
level: {REPEATABLE READ| READ COMMITTED| READ UNCOMMITTED| SERIALIZABLE
}
关键词:GLOBAL
SET GLOBAL TRANSACTION ISOLATION LEVEL level;
* 只对执行完该语句之后产生的会话起作用
* 当前已经存在的会话无效
关键词:SESSION
SET SESSION TRANSACTION ISOLATION LEVEL level;
* 对当前会话的所有后续的事务有效
* 该语句可以在已经开启的事务中间执行,但不会影响当前正在执行的事务
* 如果在事务之间执行,则对后续的事务有效。
无关键词
SET TRANSACTION ISOLATION LEVEL level;
* 只对当前会话中下一个即将开启的事务有效
* 下一个事务执行完后,后续事务将恢复到之前的隔离级别
* 该语句不能在已经开启的事务中间执行,会报错的
方式2:通过服务启动项命令
可以修改启动参数transaction-isolation的值
比方说我们在启动服务器时指定了–transaction-isolation=READ UNCOMMITTED,那么事务的默认隔离级别就从原来的REPEATABLE READ变成了READ UNCOMMITTED。
彻底搞懂 MySQL 事务的隔离级别相关推荐
- MySQL事务及隔离级别详解
MySQL事务及隔离级别详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL的基本架构 MySQL的基本架构可以分为三块,即连接池,核心功能层,存储引擎层. 1> ...
- mysql 默认事务隔离级别_上个厕所的功夫,搞懂MySQL事务隔离级别
"隔离级别" 出于MySQL四大特性(ACID)中的"I",也就是隔离性.目的是实现数据.事务一致性"C". MySQL在多线程并发场景下, ...
- 上个厕所的功夫,搞懂MySQL事务隔离级别,Java学习视频百度云盘
| 14 | 朱志鹏 | 男 | 25 | 技术1部 | 5000 | 看小说 | | 19 | 李昂 | 男 | 27 | 技术1部 | 7000 | 看片儿 | ±-±----------±--- ...
- 上个厕所的功夫,搞懂MySQL事务隔离级别
"隔离级别" 出于MySQL四大特性(ACID)中的"I",也就是隔离性.目的是实现数据.事务一致性"C". MySQL在多线程并发场景下, ...
- mysql 事务、隔离级别
一.事务的四大特性(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...
- 从根儿上理解MySQL | 事务的隔离级别与MVCC
目录 事务简介 事务的概念 MySQL中事务的语法 事务的隔离级别 事务并发执行遇到的问题 MySQL中支持的四种隔离级别 MVCC原理 版本链 ReadView MVCC小结 事务简介 事务的概念 ...
- MySQL 事务默认隔离级别?能否解决幻读?
事务隔离级别 MySQL 中事务隔离级别有 read uncommited.read commited.repeatable read.serializable 四种,其中默认为 repeatable ...
- MySQL事务的隔离级别
事务的隔离级别 隔离级别分为4种: 读未提交:READ-UNCOMMITED 读已提交: READ-COMMITTED 可重复读: REPEATABLE-READ 串行: SERIALIZABLE 当 ...
- MySQL事务学习 -- 隔离级别
6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况. 更新丢失 ...
- 从实际蹲坑中涨姿势之——彻底搞懂Mysql事务隔离级别
一.业务背景 最近在做一个类似于任务分发的平台,分为任务管理平台和作业机,任务管理平台负责接收作业机的请求,并为作业机分配任务,所有的任务都存在表t_task_info,其使用一个字段task_sta ...
最新文章
- php网课资源百度云盘_安全中国PHP网站开发工程师就业指导班 35课 附课件、源码,全套视频教程学习资料通过百度云网盘下载...
- 5.1.2 操作系统控制I/O设备的I/O控制器
- java在线预览txt、word、ppt、execel,pdf代码
- Ocelot简易教程(五)之集成IdentityServer认证以及授权
- [.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店...
- 如何使用MongoDB+Springboot实现分布式ID?
- 利用K8S技术栈打造个人私有云(连载之:K8S环境理解和练手)
- 内网穿透工具--NPS
- java 主流框架_java的三大主流框架介绍
- html drag 例子,html drag拖拽事件
- 利用重抽样获取mgcv包的广义可加模型函数曲线的可信区间(3)
- 前端EChart图表转换为图片保存到服务器路径
- [线性代数]向量2-范数三角不等式证明
- java计算机毕业设计房屋租赁系统源码+数据库+系统+lw文档+部署
- ROLAP vs MOLAP vs HOLAP
- 阿里的黄金时代|一点财经
- 全球顶级白帽子:美女、通缉犯、公务员
- Linux fcntl 函数详解
- C/C++笔试题(12)
- IRIS 2021 技术文档 First Look 12--技术概要:.NET Object Persistence with XEP
热门文章
- Andoid Activity.getWindowManager().getDefaultDisplay().getWidth()已被废弃
- rk3399_android7.1调试USB蓝牙模块小结
- rk3399_android7.1关于secureboot操作说明
- RegisterWindowMessage
- 支持rotate和大小限制的golang log库
- 《JavaScript 高级程序设计》第三章:基本概念
- 【Python3 爬虫】14_爬取淘宝上的手机图片
- poj 1503 Integer Inquiry (高精度运算)
- [外挂4] 用CE查找棋盘基址
- c语言那些细节之little-endian和big-endian