事务隔离级别小测试

事务隔离级别

本文主要对事务隔离级别做测试,以加深对隔离级别的理解。

预备操作
-- 建表
create table t_user
(
    id     int auto_increment
        primary key,
    name   varchar(255)  null,
    age    int default 0 null,
    status int default 1 null
);

-- 数据准备
insert into t_user(name, age, status) value ('zs', 11, 1);
insert into t_user(name, age, status) value ('ls', 18, 1);

-- 常用操作:修改隔离级别 session/global
set session transaction isolation level read uncommitted ; -- 读未提交
set session transaction isolation level read committed; -- 读已提交
set session transaction isolation level repeatable read; -- 可重复读
set session transaction isolation level serializable ; -- 序列化

-- 常用操作:查看隔离级别
show variables like 'transaction_isolation';
SELECT @@transaction_isolation;
读未提交

设置A和B的隔离级别为读未提交。

set session transaction isolation level read uncommitted ; -- 读未提交

操作:B开启事务,修改数据后,A去查询,然后B回滚。

-- sessionA
select * from t_user where id = 1; -- 顺序3

-- sessionB
begin; -- 顺序1
update t_user set age = 88 where id = 1; -- 顺序2
rollback ; -- 顺序4

结果:A查询到age=88,B回滚后,age=11。此时A查询到了B未提交的数据,产生了脏读。

读已提交

设置A和B的隔离级别为读已提交

set session transaction isolation level read committed; -- 读已提交

操作:还是按照读未提交测试的步骤

结果:A查询到age=11并非88,A读到的还是未提交前的数据。所以,读已提交解决了脏读问题。


操作:A开始事务,B修改数据并提交,A查询该数据,B再次修改数据并提交,A再次查询该数据。

-- sessionA
begin; -- 顺序1
select * from t_user where id = 1; -- 3
select * from t_user where id = 1; -- 5
commit; 

-- sessionB
-- 顺序2
begin;
update t_user set age = 88 where id = 1;
commit;

-- 顺序4
begin;
update t_user set age = 77 where id = 1;
commit;

结果:A第一次查询age=88,第二次查询age=77,一次事务读取的结果不一样,产生了不可重复读。

可重复读

设置A和B隔离级别为可重复读

set session transaction isolation level repeatable read; -- 可重复读

操作:还是按照读未提交测试的步骤

结果:A两次查询age都是为88。所以,读已提交解决了不可重复读的问题。


操作2:A开启事务,根据id查询某条数据,B插入了一条id相同的数据,A再次根据id查询数据,如果为空则该id插入一条数据

-- sessionA
begin; -- 顺序1
select * from t_user where id=3; -- 顺序2
select * from t_user where id=3; -- 顺序4
insert into t_user set id=3, `name`='ww', age=25, status=1; -- 顺序5
commit;

-- sessionB
-- 顺序3
begin;
insert into t_user set id=3, `name`='ww', age=25, status=1;
commit;

结果:A两次查询结果都是空,A以为可以安全插入数据,结果报主键重复问题,产生了幻觉。所以读已提交不能解决幻读的问题。

序列化

设置A和B隔离级别为可序列化

set session transaction isolation level serializable ; -- 序列化

操作:还是按照可重复读测试的步骤

结果:A开启事务后,B尝试插入一条记录,一直在等待,无法插入,原因是序列化用的级别最高的表锁。虽然序列化解决了幻读问题,但性能堪忧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值