快速理解 MySQL 事务隔离级别
当数据库上有多个事务同时执行的时候,就可能出现问题:
- 脏读(dirty read)
- 不可重复读(non-repeatable read)
- 幻读(phantom read)
为了解决这些问题,就有了“隔离级别”的概念,包括:
- 读未提交的(read uncommitted)
- 读已提交的(read committed)
- 可重复读(repeatable read)
- 串行化(serializable)
下面我们来解决3个问题:
- 脏读、不可重复读、幻读是什么意思?
- 每个隔离级别是什么含义?
- 事务隔离是怎么实现的?
事务同步问题
(1)脏读(dirty read)
示例:
在这个例子中根本不存在 id 为 1,并且 age 为 21 的记录,事务1读到了脏数据。
这就是脏读,一个事务中读到了另一个事务修改但未提交的数据。
(2)不可重复读(non-repeatable read)
示例:
不可重复读就是一个事务中读取2次同一条记录,但每次读取的结果不同。
(3)幻读(phantom read)
示例:
幻读就是在一个事务中同样的查询条件产生取得的结果不同,有新纪录产生了。
幻读其实就是不可重复读的一个特殊情况。
事务隔离级别
- 读未提交的(read uncommitted) 是指一个事务还没有提交时,它所做的变更能够被其他事务看到。
- 读已提交的(read committed) 是指一个事务只有在提交之后,它所做的变更才能被其他事务看到。
- 可重复读(repeatable read)是指一个事务中看到的数据始终是一致的。
- 串行化(serializable)会为记录加锁,出现锁冲突时,后边的事务必须等待前边的事务执行完成才能继续。
下面假设一个场景,看看不同隔离级别时的返回结果。
有一个表 T
,有一个int型字段 c
,包含一条记录 1
。
事务1 |
事务2 |
---|---|
启动事务;查询得到值1 |
启动事务 |
查询得到值1 |
|
将1改成2 |
|
查询得到值 V1 |
|
提交事务 |
|
查询得到值 V2 |
|
提交事务 |
|
查询得到值 V3 |
不同隔离级别下的值:
- 隔离级别为读未提交的
V1=2,此级别下事务2的更改可以被事务1看到。
V2 和 V3 同样为 2。
- 隔离级别为读已提交的
V1=1,V2=2,此级别下事务2未提交的变更事务1看不到,提交后事务1可以看到。
V3=2。
- 隔离级别为可重复读
V1=1,V2=1,此级别下事务1执行期间看到的值一致。
V3=2。
- 隔离级别为串行化
事务2会被锁住,等待事务1提交。V1=1,V2=1,V3=2。
事务隔离的实现
不同事务可以看到不同的值,这是怎么实现的呢?
有一个重要概念 ”回滚日志”。
MySQL中,每条记录在更新的时候都会记录一条回滚操作记录,通过回滚操作,可以得到以前某一状态的值。
例如一个值从1依次修改到4,回滚日志就类似如下的形式:
从1改为2 <- 从3改为2 <- 从4改为3 <- 当前值为4
还有一个重要概念 “视图 read-view“,事务启动时就会创建视图,与回滚日志对应起来。
例如3个事务,产生了3个视图 A B C,和回滚日志的对应关系如下:
那么事务A取得的值始终为1,其他事务同理。即使有一个新的线程把值从4改成了5,也对其他事务没影响。
- cookie、session、token三者使用
- SpringCloud注册中心集群搭建
- SpringCloud配置中心集群搭建
- HDU1846 Brave Game
- 拉格朗日插值
- python爬虫入门(二)Opener和Requests
- python爬虫入门(三)XPATH和BeautifulSoup4
- python爬虫入门(四)利用多线程爬虫
- LOJ #115. 无源汇有上下界可行流
- 数据库改名系列(数据库名,逻辑名,物理文件名)
- BZOJ1468: Tree
- 洛谷P3806 【模板】点分治1
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
- 洛谷P3383 【模板】线性筛素数(Miller_Rabin)
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解