`
wangleide414
  • 浏览: 592411 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

MySQL的事务隔离级别

 
阅读更多

问题背景:前几天在项目中遇到 两个进程 query MySQL数据不一致的情况,现象是进程A在insert 后,进程B select 不出来。后来发现 A B 都是用了事务,B中设置了autocommit = 0 表示手动提交事务。

 

问题分析:由于数据库有事务隔离机制,不同的事务隔离级别会导致两个事务查询出不同的结果。详细资料见《参考资料》,其实质就是两个不同的事务在修改增加数据后是否对另一个事务可见的问题。

 

SQL标准规定了以下四种隔离级别。

假如有A B 两个事务;

 

一、Read uncommitted (读未提交)

       最低的事务隔离级别,,在事务B未commit前,A事务就能查询到B事务中的对数据的变化。这种级别下,可能会导致脏读(dirty reads)。

 

二、Read committed(读已提交)

       在事务B commit后,事务A才能看到B 提交的数据。但是事务A中查询两次,可能两次的记录是不一样的。也就是不可以重复读。

 

三、Repeatable reads(可重复读)

 

       通过一定的锁机制,事务A 在过程中查询到的数据都是一致的。这个是MySQL的默认隔离级别。也就是说在B已经插入新数据并且commit后,在A事务中是体现不出来的。

       但是可能会产生幻读。也就是说这种级别下没有加范围锁,其他事务部能更改A所选的事务,但是可以增加新的数据。

 

四、Serializable,可串行化

       这是最高的事务隔离级别,通过对读取和更新的记录加锁,使多个事务串行工作。避免了上述碰到的各种脏读等问题。但是是以性能为代价的。

 

注:

        在数据库中运行下边代码可以查看对于的事务级别。

select @@TX_ISOLATION;

        需要注意的是,操作具体表时还需要看表的引擎,比如MyISAM 是不支持事务的,而InnoDB是支持事务的。也就是说不管你的事务隔离机制如何, MyISAM 类型的表都可以立即查询到已经真       实存储在数据库中的记录。也就是说只有支持事务的引擎才会受上边事务隔离级别的影响。

 

名词解释:

 

脏读:一个事务A可以看到另一个事务B未提交的内容。由于事务B未commit。所以数据后续可能会被rollback。在rollback后,A读取到的数据就称之为脏数据。

 

参考资料:

 

事务隔离级别:https://en.wikipedia.org/wiki/Isolation_(database_systems)

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics