mysql-isolation-level


Mysql数据库隔离级别 未完待续

MYSQL事务隔离级别

脏读 不可重复读 幻读 这周末搞定

四种隔离级别

InnoDB解决幻读的方案–LBCC&MVCC

InnoDB默认的事务隔离级别是RR,它为了解决该隔离级别下的幻读的并发问题,提出了LBCCMVCC两种方案。其中LBCC解决的是当前读情况下的幻读,MVCC解决的是普通读(快照读)的幻读。

知识点

InnoDB的RR隔离级别并没有完全解决幻读的问题。如果在同一个事务里面,只是总是执行普通的select快照读,是不会产生幻读的。

但是如果在这个事务里面通过当前读或者先更新然后快照读的形式来读取数据,就会产生幻读。

测试用表

-- auto-generated definition
create table test_read
(
    id   bigint auto_increment comment '主键'
        primary key,
    name varchar(32) default '' null comment '姓名'
)
    comment '幻读测试表';

初始化数据

insert into test_read (id, name) values (1, 'wang');
insert into test_read (id, name) values (2, 'zhang');

幻读情形1

打开两个终端,连上mysql,分别启动事务1和事务2。

事务1 事务2
start transaction; start transaction;
insert into test_read (name) values (‘zhao’);
select * from test_read; select * from test_read;

查询出来的结果如下:

事务1:

1,wang
2,zhang
3,zhao

事务2:

1,wang
2,zhang

很明显事务2没有查询到事务1未提交的新插入数据。原因也很简单,因为普通的select语句是快照读,而事务b启动时,它的快照数据就已经被版本锁定了。

如果事务2进行当前读是否能够读取到事务1未提交的新插入数据呢?

我们在事务2里面执行如下命令来看看执行结果:

select * from test_read lock in share mode;

执行完成之后我们发现事务b此时会block住,原因是事务1的insert语句排它锁住了id为3的新插入数据,而事务2想请求所有行的共享锁,肯定是需要等待的。

事务1提交之后,事务2依然无法读取到事务a新插入的数据,因为事务b还是读取到的是快照数据,所以不包含事务a提交之后的新数据。

如果此时事务b使用当前读,能否获取到事务a已提交的新插入数据呢?

事务1 事务2
start transaction; start transaction;
insert into test_read (name) values (‘zhao’);
select * from test_read; select * from test_read;
commit;
select * from test_read lock in share mode;

查询出来的结果如下:

1,wang
2,zhang
3,zhao

可以查询到事务a已提交的新数据,所以此时使用当前读就产生了幻读

幻读情形2

事务1 事务2
start transaction; start transaction;
insert into test_read (name) values (‘zhao’);
select * from test_read; select * from test_read;
commit;
update test_read set name=’bbb’ where id = 3;
select * from test_read;

第一条命令使用update更新了事务a已提交的新数据,第二条命令通过普通的select语句查看快照数据。

查询出来的结果如下:

1,wang
2,zhang
3,bbb

可以看到事务a已提交的新数据被事务b使用update语句更新了,并且通过普通的select语句给查询出来了,很显然,出现了幻读

引用

InnoDB解决幻读的方案–LBCC&MVCC


文章作者: WangQingLei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WangQingLei !
 上一篇
Java 虚拟机进程状态工具jstat Java 虚拟机进程状态工具jstat
利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对进程的classloader,compiler,gc情况;可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量,以及加载类的数量。
2022-03-28
下一篇 
synchronized锁升级与降级 synchronized锁升级与降级
针对Synchronized。在Java 5通过引入锁升级的机制来实现高效Synchronized。这三种锁的状态是通过对象监视器在对象头中的字段来表明的。偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁。降低获取锁的
2022-03-20
  目录