1、事务的隔离级别
MySQL的事务隔离级别有4种,由低到高分别是读未提交、不可重复读、可重复读和串行化。大多数数据库默认的事务隔离级别是不可重复读,而MySQL默认的事务隔离级别是可重复读。
2、不同隔离级别可能产生的问题

说明:
在可重复读的隔离级别下,Innodb使用MVCC和next-key locks解决幻读,MVCC解决的是普通读(快照读)的幻读,next-key locks解决的是当前读情况下的幻读。
3、普通读(快照读)
读取历史数据的方式,我们叫它快照读 (snapshot read)
4、当前读
读取数据库最新版本数据的方式,叫当前读 (current read)。
5、如何设置事务隔离级别
从MySQL 5.7.20开始,就增加了变量 transaction_isolation 作为 tx_isolation 的别名。从MySQL 8.0开始,变量 tx_isolation 被弃用并删除,使用 transaction_isolation 表示事务的隔离级别。
https://blog.csdn.net/max1231ff/article/details/103843560
#查询当前正在执行中的事务select * from information_schema.INNODB_TRX
6、MySQL 8.0
#查看事务隔离级别
select @@transaction_isolation;
#或者
show variables like 'transaction_isolation';
#设置事务隔离级别
set transaction_isolation ='read-uncommitted';
7、MySQL 5.x
#查看事务隔离级别
select @@tx_isolation;
#设置事务隔离级别
set tx_isolation ='read-uncommitted';
8、测试数据
create table bank_innodb(
id int not null auto_increment primary key,
name varchar(30) comment '姓名',
age int comment '年龄',
balance decimal(18, 2) comment '余额'
)engine=InnoDB default charset=utf8;
insert into bank_innodb(name, age, balance) values('zhangsan', 22, 1000);
insert into bank_innodb(name, age, balance) values('lisi', 18, 2000);
insert into bank_innodb(name, age, balance) values('wangwu', 20, 3000);
insert into bank_innodb(name, age, balance) values('zhaoliu', 21, 4000);
insert into bank_innodb(name, age, balance) values('tom', 19, 5000);
insert into bank_innodb(name, age, balance) values('jack', 24, 6000);
insert into bank_innodb(name, age, balance) values('lilei', 22, 7000);
insert into bank_innodb(name, age, balance) values('lily', 18, 8000);
9、测试
① 脏读
#查看事务隔离级别
select @@transaction_isolation;
#设置事务隔离级别
set transaction_isolation ='read-uncommitted';
事务A
# 事务A
select @@transaction_isolation;
set transaction_isolation ='read-uncommitted';
# [脏读]
begin; -- 1
select * from bank_innodb; -- 2
select * from bank_innodb; -- 5 --7
commit; -- 8
事务B
# 事务B
select @@transaction_isolation;
set transaction_isolation ='read-uncommitted';
# [脏读]
begin; -- 3
update bank_innodb set balance = balance + 100 where id = 1; -- 4
rollback; -- 6
commit; -- 9



② 不可重复读
# 事务A
select @@transaction_isolation;
set transaction_isolation ='read-committed';
# [不可重复读]
begin; -- 1
select * from bank_innodb; -- 2
select * from bank_innodb; -- 5 --7
commit; -- 8
# 事务B
select @@transaction_isolation;
set transaction_isolation ='read-committed';
# [不可重复读]
begin; -- 1
select * from bank_innodb; -- 2
select * from bank_innodb; -- 5 --7
commit; -- 8


③ 幻读
# 事务A
select @@transaction_isolation;
set transaction_isolation ='repeatable-read';
# [幻读]
begin;
select * from bank_innodb ;
select * from bank_innodb ;
insert into bank_innodb(id,name,age,balance) values(9,'john',22,9000)
commit;
# 事务B
select @@transaction_isolation;
set transaction_isolation ='repeatable-read';
# [幻读]
begin;
select * from bank_innodb ;
insert into bank_innodb(id,name,age,balance) values(9,'lucy',22,9000)
commit;
