事务隔离级别一般分为四个层级:
READ-UNCOMMITTED; 导致--->脏读、不可重复读、幻读
READ-COMMITTED; 导致--->------、不可重复读、幻读
REPEATABLE-READ; 导致--->-------、---------------、幻读
SERIALAZIBLE; 导致--->-------、---------------、-----
上图所谓的表应该没什么说的。今天在dos下想要进行验证,发现得不到验证的结果。过程如下:
一、验证一
1、打开两个dos窗口A、B连接本地mysql;
2、mysql默认的global隔离级别为REPEATABLE-READ,查看方式为(select @@global.tx_isolation)。
A设置session的隔离级别为READ-UNCOMMITTED,方式为(set tx_isolation = 'READ-UNCOMMITTED')。
B的隔离级别还是默认的REPEATABLE-READ.
3、B窗口打开事务(begin或start transaction),更新测试表的测试数据。update操作
4、A窗口打开事务(方式和步骤3一致),查询测试表的测试数据,此时发现测试数据已经修改。
5、B执行回滚(rollback),查询发现步骤3的更新已经回滚;
6、A查询测试表的测试数据,发现也已经回滚。
?问题不应该是A查询的数据还是更新后的脏数据吗?
二、验证二
步骤1和验证一一致;
1、
2、B窗口打开事务(begin或start transaction),更新测试表的测试数据。update操作
3、A窗口打开事务(方式和步骤3一致),查询测试表的测试数据,此时发现测试数据已经修改。
?问题不应该是A窗口读的数据应该是没有更新的数据吗?因为A的默认隔离级别为REPEATABLE-READ
当时考虑可能是mysql的自动提交惹的祸,查看mysql的自动提交设置(show variables like 'autocommit')
mysql的默认自动提交,修改A、B的autommit为手动,(set autocommit = 0)
然后再进行验证,结果一样,请大牛们解惑,谢谢
insert into tb(id,v)
select 1,'data1' union all
select 2,'data2' union all
select 3,'data3' union all
select 4,'data4';/*
drop table tb;
*/
connection 1, session 1:/*session 1*/
set autocommit=0;
set session transaction isolation level read uncommitted;
start transaction; update tb set v=concat(v,'_new') where id>=3;select * from tb where id>=3;select @@tx_isolation;
connection 2,session 2:/*session 2*/
set autocommit=0;
start transaction;
update tb set v=concat(v,'_o') where id>=4;insert into tb(id,v) select 5,'data5';select * from tb where id>=3;select @@tx_isolation;先执行session 1代码,再执行session2代码,
你会发现,session 2中,sql执行到update语句,会一直在等待状态。