MySQL中四种隔离级别的演示
事务的隔离是并发操作中需要理解清楚的问题.MySQL中共有4种不同的隔离级别,这4种隔离级别分别是:
| 隔离级别类型 | 影响结果 |
| READ UNCOMMITTED(未提交读) | 事务将会读取到未提交的数据,可能会造成脏读、可重复读和幻读的现象,是一种较低的隔离级别,在实际中较少使用 |
| READ COMMITTED(提交读) | 该种隔离级别在事务1没有提交或回滚时,事务2可避免脏读,但是在事务1提交或回滚之后,事务2出现了可重复读和幻读的情况 |
| REPEATABLE READ(可重复读) | 可重复读是MySQL默认的隔离级别,可以有效避免脏读和可重复读的情况,但是不能避免幻读 |
| SERIABLIZABLE(串行化) | 可以同时解决脏读、可重复读和幻读的情况,但是由于会出现阻塞的情况,所以实际中也较少使用 |
可以看出,不同的隔离级别有不同的多事务执行结果。MySQL中的InnoDB存储引擎的默认的隔离级别是可重复读(REPEATABLE READ).
本文使用演示了上表中所列出的4种隔离级别(基于MySQL5.7).使用的表为test,test中的字段分别是id、name.
mysql> select * from test;
+------+-------+
| id | name |
+------+-------+
| 100 | zhangsan |
| 200 | lisi |
+------+-------+
由于MySQL中默认开启的是隐式事务,所以为了操作的效果不受影响,需要将事务开启成显式的.同时启动了两个会话窗口,并将启动的两个会话窗口都需要如此操作.在第一个窗口执行:
mysql> set autocommit=0;
1、READ UNCOMMITTED
由下面的查询结果可以看出,MySQL中默认的隔离级别为REPEATABLE READ:
mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
因此需要将默认的隔离级别设置为READ UNCOMMITED:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Query OK, 0 rows affected (0.00 sec)
(1)在第一个窗口执行:
mysql> UPDATE test SET name='wangwu' WHERE id=100;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
(2)在第二个窗口中查询test表:
mysql> SELECT * FROM test;
+------+--------+
| id | name |
+------+--------+
| 100 | wangwu |
| 200 | lisi |
+------+--------+
2 rows in set (0.00 sec)
从上面的输出结果中可以看出,id=100对应的name为wangwu.
(3)接着在第一个窗口中执行ROLLBACK操作,再次在第二个窗口查询时,id=100对应的name为zhangsan,说明了READ UNCOMMITTED隔离级别不可避免脏读.这里没有测试可重读读和幻读的情况了,因为如果脏读没有避免,那么也会出现可重复读和幻读的情况.
mysql> select * from test;
+------+----------+
| id | name |
+------+----------+
| 100 | zhangsan |
| 200 | lisi |
+------+----------+
2 rows in set (0.00 sec)
2、READ COMMITTED
将第一个和第二个窗口的隔离级别都设置为:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)
在第一个窗口重新开启一个事务:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
接着在第一个窗口执行(此时没有进行commit或rollback操作):
mysql> update test set name='wangwu' where id=100;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
在第二个窗口中查询test:
mysql> select * from test;
+------+----------+
| id | name |
+------+----------+
| 100 | zhangsan |
| 200 | lisi |
+------+----------+
2 rows in set (0.00 sec)
通过上面的输出结果可知,使用了READ COMMITTED隔离级别后,没有出现脏读的情况。但是当在窗口一中执行commit时,从窗口二中查询得到的结果已经发生改变:
mysql> select * from test;
+------+--------+
| id | name |
+------+--------+
| 100 | wangwu |
| 200 | lisi |
+------+--------+
2 rows in set (0.00 sec)
从而可知,提交前和提交后得到的两种情况不相同,从而说明了READ COMMITTED不能避免可重复读。
3、REPEATABLE READ
开始前的数据:
mysql> select * from test;
+------+----------+
| id | name |
+------+----------+
| 100 | zhangsan |
| 200 | lisi |
+------+----------+
2 rows in set (0.00 sec)
同样的,将第一个和第二个窗口的隔离级别都设置为:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Query OK, 0 rows affected (0.00 sec)
第一个窗口执行:
mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.00 sec)
在第一个窗口更新test中的name:
mysql> UPDATE test set name='xiaoming' where id=100;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
在第二个窗口查询test:
mysql> select * from test;
+------+----------+
| id | name |
+------+----------+
| 100 | zhangsan |
| 200 | lisi |
+------+----------+
2 rows in set (0.00 sec)
此时发现,在第二个窗口中查询的数据并没有发生改变,REPEATABLE READ可以避免脏读。
同时,当第一个窗口提交更新后,在第二个窗口中执行查询时,数据没有发生变化,说明此时也避免了可重复读的情况。
mysql> select * from test;
+------+----------+
| id | name |
+------+----------+
| 100 | zhangsan |
| 200 | lisi |
+------+----------+
2 rows in set (0.00 sec)
在第二个窗口中无论读取多少次,读取到的数据都不会是第一个窗口中更新的数据,只有当第二个窗口也提交时,此时的第二个窗口才会更新数据。
mysql> select * from test;
+------+----------+
| id | name |
+------+----------+
| 100 | xiaoming |
| 200 | lisi |
+------+----------+
2 rows in set (0.00 sec)
最后,在第二个窗口插入一条数据:
mysql> insert into test values(300,'wangwu');
Query OK, 1 row affected (0.00 sec)
在第一个窗口更新数据,按道理来说,应该会有两行数据受影响,但是此时发现有三行数据受影响了,说明了出现了幻读的现象:
mysql> update test set name='zhaoliu';
Query OK, 3 rows affected (6.36 sec)
Rows matched: 3 Changed: 3 Warnings: 0
4、 SERIALIZABLE
将第一个和第二个窗口的隔离级别都设置为:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Query OK, 0 rows affected (0.00 sec)
开始操作前的数据:
+------+---------+
| id | name |
+------+---------+
| 100 | zhaoliu |
| 200 | zhaoliu |
| 300 | zhaoliu |
+------+---------+
3 rows in set (0.00 sec)
当在窗口2中执行插入操作时,会发生阻塞现象,因为此时窗口1没有提交(即没有释放锁),只有当窗口1执行提交操作时,窗口2中的数据更插入成功。
本文通过实验的方式对MySQL中的四种隔离级别进行验证。可以有效加深对这四种隔离级别的理解。
如有错误,请指正。谢谢
MySQL中四种隔离级别的演示的更多相关文章
- MySQL中四种常用存储引擎的介绍
MySQL常用的四种引擎的介绍 (1):MyISAM存储引擎: 不支持事务.也不支持外键,优势是访问速度快,对事务完整性没有 要求或者以select,insert为主的应用基本上可以用这个引擎来创建表 ...
- mysql中四种存储引擎的区别和选择
前言 数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建.查询.更新和删除数据.不同的存储引擎提供不同的存储机制.索引技巧.锁定水平等功能,使用不同的存储引擎,还可以 ...
- MySQL ACID及四种隔离级别的解释
以下内容出自<高性能MySQL>第三版,了解事务的ACID及四种隔离级有助于我们更好的理解事务运作. 下面举一个银行应用是解释事务必要性的一个经典例子.假如一个银行的数据库有两张表:支票表 ...
- [转载] MySQL的四种事务隔离级别
本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...
- MySQL有四种BLOB类型
先说明一下Blob的类型,直接从网上摘抄了!!!1.MySQL有四种BLOB类型: ·tinyblob:仅255个字符 ·blob:最大限制到65K字节 ·mediumblob:限制到16M字节 ·l ...
- MySql中4种批量更新的方法update table2,table1,批量更新用insert into ...on duplicate key update, 慎用replace into.
mysql 批量更新记录 MySql中4种批量更新的方法最近在完成MySql项目集成的情况下,需要增加批量更新的功能,根据网上的资料整理了一下,很好用,都测试过,可以直接使用. mysql 批量更新共 ...
- Java中四种引用:强、软、弱、虚引用
这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...
- [转]C++中四种类型转换符的总结
C++中四种类型转换符的总结 一.reinterpret_cast用法:reinpreter_cast<type-id> (expression) reinterpret_cast操 ...
- AX中四种库存ABC分析法原理研究
库存ABC分类,简单的说就是抓大放小,是为了让我们抓住重点,用最大精力来管理最重要的物料,而对于不太重要的物料则可以用较少的精力进行管理.它和我们平常说的八二法则有异曲同工之妙. 既然要应用库存ABC ...
随机推荐
- 朋友聚会,下馆子要到哪家饭馆?——单样本T检验帮你找到答案
聚会时,五花八门的饭馆让人眼花缭乱,应该到哪家店吃呢?除了美味的食物,良好的服务态度也是好饭馆的必备品质,如何判断一家饭馆的服务态度如何?此时可以用单样本T检验来找答案~ 让顾客对A饭馆的服务态度 ...
- [企业微信通知系列]Jenkins发布后自动通知
一.前言 最近使用Jenkins进行自动化部署,但是部署后,并没有相应的通知,虽然有邮件发送通知,但是发现邮件会受限于接收方的接收设置,导致不能及时看到相关的发布内容.而由于公司使用的是企业微信,因此 ...
- node.js常用的全局成员和对象
一般可以直接调用的对象,我们称之为全局对象: 一下对象都加了console.log(),以在运行环境中的显示效果为标准 //包含文件名称的全路径: console.log(_filename); ...
- P2698 [USACO12MAR]花盆Flowerpot 单调队列
https://www.luogu.org/problemnew/show/P2698 警示 用数组写双端队列的话,记得le = 1, ri = 0:le<=ri表示队列非空 题意 求一个最小的 ...
- Codeforces 1058 D. Vasya and Triangle 分解因子
传送门:http://codeforces.com/contest/1058/problem/D 题意: 在一个n*m的格点中,问能否找到三个点,使得这三个点围成的三角形面积是矩形的1/k. 思路: ...
- hdu 5977 Garden of Eden(点分治+状压)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5977 题解:这题一看就知道是状压dp然后看了一下很像是点分治(有点明显)然后就是简单的点分治+状压dp ...
- Flask源码浅析
前言 学习一样东西,要先知其然,然后知其所以然. 这次,我们看看Flask Web框架的源码.我会以Flask 0.1的源码为例,把重点放在Flask如何处理请求上,看一看从一个请求到来到返回响应都经 ...
- eql框架。
在刚进入公司的时候,在service层的框架用的是eql,是公司内的大佬封装的,作为一个小白,真的是折磨.公司内没有任何的文档,只能靠着自己一步一步的摸索. 后来用习惯了,发现这个框架确实有自己的独到 ...
- stm32f10x基于freeRTOS的低功耗实现
0. 写在前面 没有太多时间更新,可能偶尔有时间就更新一些. 因为突然有项目用到了stm32f10x系列并且是电池驱动的,所以需要对功耗进行优化,其他CM3核心系列应该也同样适用. 1. 背景 Stm ...
- python自学Day02(自学书籍python编程从入门到实践)
第三章 列表简介 3.1 列表是什么 按特定顺序排列的元素组成. 元素类型可以是任意数据类型. 元素之间没有任何的关系. 在python中用中括号 [] 括起来并用 ,号隔开 3.1.1 访问列表元素 ...