码迷,mamicode.com
首页 > 其他好文 > 详细

事务隔离级别理解

时间:2015-08-02 13:51:35      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:

主要参考博客:http://www.cnblogs.com/zhoujinyi/p/3437475.html

基本隔离级别
简介

===========================================================================================
       隔离级别               脏读(Dirty Read)          不可重复读(NonRepeatable Read)     幻读(Phantom Read) 
===========================================================================================

未提交读(Read uncommitted)        可能                            可能                       可能 

已提交读(Read committed)          不可能                          可能                        可能 

可重复读(Repeatable read)          不可能                          不可能                     可能 

可串行化(Serializable )                不可能                          不可能                     不可能 

===========================================================================================

数据准备

    新建Student表。

  1. CREATE TABLE `student` (
  2.  `id` int(8) NOT NULL AUTO_INCREMENT,
  3.  `name` varchar(120) DEFAULT NULL,
  4.  `class` varchar(120) DEFAULT NULL,
  5.  PRIMARY KEY (`id`)
  6. ) ENGINE=InnoDB DEFAULT CHARSET=latin1
引擎采用InnoDB,InnoDB默认采用可重复读的隔离级别。
隔离级别基本理解

    未提交读(Read uncommitted):允许脏读,就是可能读取到其他回话中未提交事务修改的数据。个人觉得可以理解为读取未提交数据。

    提交读(Read committed):只能读取到已经提交事务的数据。Oracle数据库的默认级别。

    可重复读(Repeatable read):可重复读。  同一个事务的查询都是同事务开始时刻一致。InnoDB默认级别,该级别消除了不可重复读,但是存在幻读。

    可串行化(Serializable)  :完全串行化的读,每次读都会获取表级共享锁。

隔离级别简介
    脏读

   1, 脏读:一个会话中的事务访问数据,并对数据进行了修改,事务未提交的时候,另一个事务也可以访问这个数据。

    2,场景

    首先查看数据库事务级别:

  1. select @@global.tx_isolation;
    结果:
  1. REPEATABLE-READ

    在session1中执行如下操作:

  1. start transaction;;
  2. insert into student(id, class, name)values(null, 1, ‘a1‘);

事务未提交。

在session2中执行查询操作,因为默认事务级别是REPEATABLE-READ,所以不会查到数据。

  1. select * from student

再返回session1中,执行

  1. COMMIT;

session2,中查询即可查询到数据。

 在此级别中避免了脏读,但是如果事务级别是在未提交读(Read uncommitted),则可以查询到数据,产生脏读。

不可重复读

    1,不可重复读:是指在一个事务内,多次读同一个数据。在这个事务还没有结束的时候,另一个事务也访问了该数据。那么第一个事务中两次读数据之间,由于第二个事务的更改,可能导致第一个事务两次的数据是不一致的。这样子就导致一次事务内两次读取到的数据是不一致的不可重复读。

    2,场景。


可重复读

    1,可重复读:与不可重复读相反,一个事务内部,多次读取同一个事务,保证数据读取一致。

    2,场景

查看数据库隔离级别:

  1. select @@global.tx_isolation;

查询结果:

  1. REPEATABLE-READ

session 1:开启事务,并查询数据:

  1. start TRANSACTION;
  2. select * from student;

查询结果:

  1. 1 a1 1

session2:开启事务,修改学生姓名为a2并提交事务。

  1. start TRANSACTION;
  2. update student set name = ‘a2‘ where id = 1;
  3. commit;

session1:再次执行查询:

  1. 1 a1 1

查询结果与之前保持一致。

session1:事务提交,并执行查询。

  1. commit;
  2. select * from student;

查询结果:

  1. 1 a2 1
如上我们可以看到,查询结果和数据库保持一致。


幻读

    1,幻读:第一个事务对表中的数据进行了修改,这种修改涉及到修改表中所有数据行,同时第二个事务向表中插入一行数据。那么,以后第一个事务就会发现,存在数据行未修改,好像产生幻读一样。

    2,场景

 查看数据库的事务策略

  1. select @@global.tx_isolation;

结果:

  1. REPEATABLE-READ

session1:启动事务,并修改表中所有数据name为a3。

  1. start TRANSACTION;
  2. update student set name = ‘a3‘;

session2:启动事务,插入一条新纪录。并提交事务。

  1. start TRANSACTION;
  2. insert into student values(null, ‘a2‘, 1);

在执行此时,会发现数据库执行会等待之前语句执行,而不会发生如之前版本的幻读。

session1:执行commit。

  1. commit;
发现session2,的语句执行结束。session2 事务commit。

本人使用的数据库版本为:Mysql 5.6。并未发生幻读现象。


如上即为四中事务隔离级别的基本理解。


版权声明:本文为博主原创文章,未经博主允许不得转载。如有问题,欢迎交流。

事务隔离级别理解

标签:

原文地址:http://blog.csdn.net/mergades/article/details/47205635

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!