MySQL/InnoDB中的事务隔离级别
SQL标准中的事务四种隔离级别
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
未提交读(Read uncommitted) | 可能 | 可能 | 可能 |
已提交读(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
- 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
- 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
- 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
- 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
未提交读(Read uncommitted)
数据库一般都不会用,而且任何操作都不会加锁
mysql> select * from tx_test;
+----+-------+
| id | value |
+----+-------+
| 1 | a |
+----+-------+
1 row in set (0.00 sec)
由于MySQL的InnoDB默认是使用的RR级别,所以我们先要将该session开启成RU级别
SET session transaction isolation level read uncommitted;
_____________________________________________________________________
事务A 事务B
_____________________________________________________________________
begin;
begin;
_____________________________________________________________________
select * from tx_test;
______________
id value
______________
1 a
______________
___________________________________________________________________
insert into tx_test(value) values('b');
____________________________________________________________________
select * from tx_test;
______________
id value
______________
1 a
______________
2 b
______________
读到事务A还未commit的行,出现脏读
_____________________________________________________________________
commit;
commit;
_____________________________________________________________________
已提交读(Read committed)
在RC级别中,数据的读取都是不加锁的,但是数据的写入、修改和删除是需要加锁的。
SET session transaction isolation level read committed;
SET SESSION binlog_format = 'ROW';(或者是MIXED)
_____________________________________________________________________
事务A 事务B
_____________________________________________________________________
begin; begin;
_____________________________________________________________________
update tx_test set value='aa' where id=1; update tx_test set value='aaa' where id=1;
___________________________________________________________________________________________
ERROR 1205 (HY000): Lock wait timeout exceeded;
try restarting transaction
_____________________________________________________________________
commit;
_____________________________________________________________________
为了防止并发过程中的修改冲突,事务A中MySQL给id=1的数据行加锁,并一直不commit(释放锁),那么事务B也就一直拿不到该行锁,wait直到超时。
可重复读(Repeatable read)
这是MySQL中InnoDB默认的隔离级别。我们姑且分“读”和“写”两个模块来讲解。
读
读就是可重读,可重读这个概念是一事务的多个实例在并发读取数据时,会看到同样的数据行。
RC模式下的展现(不可重读)
__________________________________________________________________________________________
事务A 事务B
__________________________________________________________________________________________
begin;
begin;
__________________________________________________________________________________________
select * from tx_test;
______________
id value
______________
1 aa
______________
2 b
______________
__________________________________________________________________________________________
update tx_test set value='bb' where id=2;
__________________________________________________________________________________________
commit;
__________________________________________________________________________________________
select * from tx_test;
______________
id value
______________
1 aa
______________
2 bb
______________
读到了事务B修改的数据,和第一次查询的结果不一样,
是不可重读的。
_________________________________________________________________________________________
commit
_________________________________________________________________________________________
事务B修改id=2的数据提交之后,事务A同样的查询,后一次和前一次的结果不一样,这就是不可重读(重新读取产生的结果不一样)。这就很可能带来一些问题,那么我们来看看在RR级别中MySQL的表现:
事务A 事务B 事务C
_________________________________________________________________________________________________________________________________________
begin;
begin; begin;
_________________________________________________________________________________________________________________________________________
select * from tx_test;
______________
id value
______________
1 aa
______________
2 bb
______________
___________________________________________________________________________________________________________________________________________
update tx_test set value='aaa' where id=1; insert into tx_test(value) values('c');
___________________________________________________________________________________________________________________________________________
commit; commit;
____________________________________________________________________________________________________________________________________________
select * from tx_test;
______________
id value
______________
1 aa
______________
2 bb
______________
没有读到事务B修改的数据,和第一次sql读取的一样,是可重复读的。
没有读到事务C新添加的数据。
_________________________________________________________________________________________
commit
_________________________________________________________________________________________
我们注意到,事务A先做了一次读取,事务B中间修改了id=1的数据,并commit之后,事务A第二次读到的数据和第一次完全相同。所以说它是可重读的。
不可重复读和幻读的区别
不可重复读重点在于update和delete,而幻读的重点在于insert。
如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。
所以说不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题。
上文说的,是使用悲观锁机制来处理这两种问题,但是MySQL、ORACLE、PostgreSQL等成熟的数据库,出于性能考虑,都是使用了以乐观锁为理论基础的MVCC(多版本并发控制)来避免这两种问题。
可串行化(Serializable )
读加共享锁,写加排他锁,读写互斥。使用的悲观锁的理论,实现简单,数据更加安全,但是并发能力非常差。如果你的业务并发的特别少或者没有并发,同时又要求数据及时可靠的话,可以使用这种模式。
参考链接:
1.https://tech.meituan.com/innodb-lock.html
2.http://hedengcheng.com/?p=771
MySQL/InnoDB中的事务隔离级别的更多相关文章
- MySQL InnoDB中的事务隔离级别和锁的关系
前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力. ...
- 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系
重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...
- 【转载】Innodb中的事务隔离级别和锁的关系
前言 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所 ...
- Innodb中的事务隔离级别和锁的关系(转载)
nodb中的事务隔离级别和锁的关系 原文:https://tech.meituan.com/innodb-lock.html ameng ·2014-08-20 15:50 前言: 我们都知道事务的几 ...
- Innodb中的事务隔离级别和锁的关系
前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力. ...
- Innodb中的事务隔离级别和锁的关系(转)
原文:http://tech.meituan.com/innodb-lock.html 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库 ...
- Innodb 中的事务隔离级别和锁的关系
转自:https://tech.meituan.com/innodb-lock.html 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据 ...
- MySQL数据库引擎、事务隔离级别、锁
MySQL数据库引擎.事务隔离级别.锁 数据库引擎InnoDB和MyISAM有什么区别 大体区别为: MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能 ...
- 【原创】互联网项目中mysql应该选什么事务隔离级别
摘要 企业千万家,靠谱没几家. 社招选错家,亲人两行泪. 祝大家金三银四跳槽顺利! 引言 开始我们的内容,相信大家一定遇到过下面的一个面试场景 面试官:"讲讲mysql有几个事务隔离级别?& ...
随机推荐
- Halcon算子函数
Chapter_1_:Classification 1.1 Gaussian-Mixture-Models 1.add_sample_class_gmm 功能:把一個訓練樣本添加到一個高斯混合模型的 ...
- Mac下通过FFMpeg实现Android手机推流和播放
一.Mac下搭建推流服务器(Nginx+RTMP+FFMpeg) 安装x264 git clone git://git.videolan.org/x264.git cd x264 ./configur ...
- git clone 新项目时,报error: RPC failed; curl 18 transfer closed with outstanding read data remaining
error: RPC failed; curl 18 transfer closed with outstanding read data remaining fatal: The remote en ...
- 序列化模块ModelSerializer上补充及ListSerializer
整体单改 路由层.模型层.序列化层不需要做修改,只需要处理视图层:views.py """ 1) 单整体改,说明前台要提供修改的数据,那么数据就需要校验,校验的数据应该在 ...
- C++如何保留2位小数输出
cout<<setiosflags(ios::);//需要头文件#include <iomanip> 然后再输出实数类型变量即可以保留2位小数输出了,当然你要保留三位小数,se ...
- 如何进行Web服务的性能测试
涉及到web服务的功能在不断的增加,对于我们测试来说,我们不仅要保证服务端功能的正确性,也要验证服务端程序的性能是否符合要求.那么性能测试都要做些什么呢?我们该怎样进行性能测试呢? 性能测试 ...
- 差旅日志i·长安&北京(更新于8.21_夜)
大学之时,看到zealer王自如的差旅日志系列欲罢不能,扁平化的管理理念以及轻松的工作氛围,耳目一新的出差体验,抵消了部分不曾走入职场的紧张感甚至是恐惧感.如今初入职场也进入了职业生涯,特记录此次的差 ...
- Android中的路径记录
Android中的路径记录 | RobinBlog 导航 导航 博客 分类 标签 友链 关于 搜索 Environment.getDataDirectory().getPath()=/dataEnvi ...
- React Native Build Apk
1 React Native安卓项目打包APK 1.1 产生签名的key 先通过keytool生成key 1 keytool -genkey -v -keystore demo-release-key ...
- Ta说:2016微软亚洲研究院第二届博士生论坛
"聚合多元人才创造无尽可能,让每一位优秀博士生得到发声成长机会"可以说是这次微软亚洲研究院博士生论坛最好的归纳了.自去年首次举办以来,这项旨在助力青年研究者成长的项目迅速得到了 ...