主要参考博客:http://www.cnblogs.com/zhoujinyi/p/3437475.html
基本隔离级别
简介
===========================================================================================
隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
===========================================================================================
未提交读(Read uncommitted) 可能 可能 可能
已提交读(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable )
不可能 不可能 不可能
===========================================================================================
数据准备
新建Student表。
CREATE TABLE `student` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`name` varchar(120) DEFAULT NULL,
`class` varchar(120) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
引擎采用InnoDB,InnoDB默认采用可重复读的隔离级别。
隔离级别基本理解
未提交读(Read uncommitted):允许脏读,就是可能读取到其他回话中未提交事务修改的数据。个人觉得可以理解为读取未提交数据。
提交读(Read committed):只能读取到已经提交事务的数据。Oracle数据库的默认级别。
可重复读(Repeatable read):可重复读。 同一个事务的查询都是同事务开始时刻一致。InnoDB默认级别,该级别消除了不可重复读,但是存在幻读。
可串行化(Serializable) :完全串行化的读,每次读都会获取表级共享锁。
隔离级别简介
脏读
1, 脏读:一个会话中的事务访问数据,并对数据进行了修改,事务未提交的时候,另一个事务也可以访问这个数据。
2,场景
首先查看数据库事务级别:
select @@global.tx_isolation;
结果:
REPEATABLE-READ
在session1中执行如下操作:
start transaction;;
insert into student(id, class, name)values(null, 1, ‘a1‘);
事务未提交。
在session2中执行查询操作,因为默认事务级别是REPEATABLE-READ,所以不会查到数据。
select * from student
再返回session1中,执行
COMMIT;
session2,中查询即可查询到数据。
在此级别中避免了脏读,但是如果事务级别是在未提交读(Read uncommitted),则可以查询到数据,产生脏读。
不可重复读
1,不可重复读:是指在一个事务内,多次读同一个数据。在这个事务还没有结束的时候,另一个事务也访问了该数据。那么第一个事务中两次读数据之间,由于第二个事务的更改,可能导致第一个事务两次的数据是不一致的。这样子就导致一次事务内两次读取到的数据是不一致的不可重复读。
2,场景。
可重复读
1,可重复读:与不可重复读相反,一个事务内部,多次读取同一个事务,保证数据读取一致。
2,场景
查看数据库隔离级别:
select @@global.tx_isolation;
查询结果:
REPEATABLE-READ
session 1:开启事务,并查询数据:
start TRANSACTION;
select * from student;
查询结果:
1 a1 1
session2:开启事务,修改学生姓名为a2并提交事务。
start TRANSACTION;
update student set name = ‘a2‘ where id = 1;
commit;
session1:再次执行查询:
1 a1 1
查询结果与之前保持一致。
session1:事务提交,并执行查询。
commit;
select * from student;
查询结果:
1 a2 1
如上我们可以看到,查询结果和数据库保持一致。
幻读
1,幻读:第一个事务对表中的数据进行了修改,这种修改涉及到修改表中所有数据行,同时第二个事务向表中插入一行数据。那么,以后第一个事务就会发现,存在数据行未修改,好像产生幻读一样。
2,场景
查看数据库的事务策略
select @@global.tx_isolation;
结果:
REPEATABLE-READ
session1:启动事务,并修改表中所有数据name为a3。
start TRANSACTION;
update student set name = ‘a3‘;
session2:启动事务,插入一条新纪录。并提交事务。
start TRANSACTION;
insert into student values(null, ‘a2‘, 1);
在执行此时,会发现数据库执行会等待之前语句执行,而不会发生如之前版本的幻读。
session1:执行commit。
commit;
发现session2,的语句执行结束。session2 事务commit。
本人使用的数据库版本为:Mysql 5.6。并未发生幻读现象。
如上即为四中事务隔离级别的基本理解。
版权声明:本文为博主原创文章,未经博主允许不得转载。如有问题,欢迎交流。