mysql中四种事务隔离描述不正确_23 mysql的四种事务隔离级别

数据库的隔离级别是在并发度和安全性之间做平衡。mysql支持四种事务隔离级别,分别是:Read Uncommitted(读取未提交内容)]、Read Committed(读取提交内容)、Repeatable Read(可重读)、Serializable(可串行化),这四种隔离级别并发度越来越低,但安全性越来越高。mysql的默认隔离级别是REPEATABLE-READ,即可重复读。本文将详细介绍数据库的四种隔离级别之表现。

1、环境约束

win10 64

mysql 5.7.27

2、前提约束

已经安装好数据库

https://www.jianshu.com/p/74c291a79fa3

确保数据库中已经有一张表t_user,打开命令行,请执行以下代码:

# 登录到mysql

mysql -uroot -pzhangli

# 创建一张表

create table t_user(id int,name varchar(20));

# 插入2条记录

insert into t_user(id,name) values(1,'ali');

insert into t_user(id,name) values(2,'zhangli');

3、操作步骤

3.1 准备工作

打开两个命令行,都登录到mysql,左边的表格命名为1,右边的表格命名为2,如下图:

d055d1f927821178b1b86a00061cdd9a.png

由上图课件,mysql的默认隔离级别是Repeatable-Read。

3.2 测试Read Uncommitted

设置数据库隔离级别为Read Uncommitted,在命令行1、命令行2中都执行设置语句:

# 设置隔离级别为READ-UNCOMMITTED

set tx_isolation='READ-UNCOMMITTED';

# 查看隔离级别

select @@tx_isolation;

74dc4433c8ef9fd7bf83dd2380d2b776.png

在右边命令行中执行以下语句:

# 开启命令行的事务

start transaction;

在左边命令行中执行以下语句:

# 开启命令行的事务,两个事务产生重合

start transaction;

# 修改ali为zhangli

update t_user set name='zhangli' where id=1;

# 查看t_user表,显然已经改变

select * from t_user;

在右边命令行中执行以下语句:

# 查看t_user表,显然查到了左边命令行中修改但是未提交的数据,这就是脏读

select * from t_user

1ec13c947e5f0263d790917f58e6a5fd.png

在左边命令行1中执行以下语句:

# 回滚

rollback;

# 查看t_user表,回滚到之前数据

select * from t_user;

在右边命令行中执行以下语句:

# 查看t_user表,也回滚到之前数据

select * from t_user;

# 回滚,关闭事务,恢复到没有事务的状态

rollback;

90c75b455d53b0068b05d3126ed2337f.png

由此可见,“READ-UNCOMMITTED”隔离级别使得一个事务可以读取另一个事务没有提交的数据。

3.3 测试Read Committed

设置数据库隔离级别为Read Committed,在命令行1、命令行2中都执行设置语句:

# 设置隔离级别为read-committed

set tx_isolation='read-committed';

# 查看隔离级别

select @@tx_isolation;

fbf2660497efc6a6d293486f2f98f164.png

在右边命令行中执行以下语句:

# 开启命令行2的事务

start transaction;

在左边命令行中执行以下语句:

# 开启命令行的事务,两个事务产生重合

start transaction;

# 修改ali为zhangli

update t_user set name='zhangli' where id=1;

# 查看t_user表,显然已经改变

select * from t_user;

在右边命令行中执行以下语句:

# 查看t_user表,显然还是以前的数据,这就证明了“read-committed”级别不能读取未提交的事务

select * from t_user;

ac1c4203351d42898dac225bdf057d48.png

在左边命令行执行以下语句:

# 提交

commit;

# 查看数据

select * from t_user;

在右边命令行执行以下语句:

# 查看数据,此时看到了新的数据“zhangli”,这就证明了“read-committed”级能读取已提交的事务

select * from t_user

# 回滚,关闭事务,恢复到没有事务的状态

rollback;

1a27104417319da7ef95c19e41c91464.png

然而,此时右边命令行是委屈的,它在同一个事务中啥都没干,却查到了两个不同的数据,这就是不可重复读。

208d74a71ae4eb9c3df8883b8286c1b4.png

由此可见,“READ-COMMITTED”隔离级别使得一个事务只能读取另一个事务提交的数据,但是不能解决不可重复读。

3.4 测试Repeatable Read

设置数据库隔离级别为Repeatable Read,在命令行1、命令行2中都执行设置语句:

# 设置隔离级别为repeatable-read

set tx_isolation='repeatable-read';

# 查看隔离级别

select @@tx_isolation;

a672a48d4bfb438648cedfbb28639ed1.png

在右边命令行中执行以下语句:

# 开启命令行2的事务

start transaction;

在左边命令行中执行以下语句:

# 开启命令行的事务,两个事务产生重合

start transaction;

# 修改ali为zhangli

update t_user set name='xiaoli' where id=1;

# 查看t_user表,显然已经改变

select * from t_user;

在右边命令行中执行以下语句:

# 查看t_user表,当然还是以前的数据,因为"repeatable read"比"read-committed"更为严格,所以更加不能读取未提交的事务

select * from t_user;

9e5d534be0ae9c37513294bf15e0517b.png

在左边命令行中执行以下语句:

# 提交

commit;

# 查看

select * from t_user;

在右边命令行中执行以下语句:

# 先查看,还是之前的数据

select * from t_user;

# rollback以关闭事务

rollback;

# 再次查看,才看到了新的数据,这就说明,可重复读解决了不可重复读的问题。

select * from t_user;

1590a5de9e0f66a04a423436034cbe9e.png

但是,Repeatable Read不能解决幻读的问题,请执行以下语句:

# 在左边命令行执行

start transaction;

# 在右边命令行执行

start transaction;

# 在左边命令行执行

insert into t_user(id,name) values(3,'ali');

commit;

select * from t_user;

# 在右边命令行执行,还是只能看到两行记录

select * from t_user;

commit;

select * from t_user; # 在我的事务过程中没加入记录,却看到了3行记录,还以为眼花了,幻读了

3.5 测试Serializable

设置数据库隔离级别为Serializable,在命令行1、命令行2中都执行设置语句:

# 设置隔离级别为serializable

set tx_isolation='serializable';

# 查看隔离级别

select @@tx_isolation;

b373edfcbbdc8cf1ab0615a66dc06178.png

在右边命令行中执行以下语句:

# 开启命令行2的事务

start transaction;

在左边命令行中执行以下语句:

start transaction;

insert into t_user(id,name) values(4,'zhangli');# 这时候是执行不下去的,因为可序列化约束了最严格的的隔离级别,事务之间不能重合。

在右边命令行执行以下语句:

commit;# 在提交执行的瞬间,左边的insert可以向下执行,因为事务没有重合了

# 再次查询,还是之前的记录

select * from t_user

在左边命令行执行以下命令:

commit;

# 能看到最新的记录

select * from t_user;

在右边命令行执行以下命令:

# 看到了最新的记录

select * from t_user

可见,序列化约束了最严格的隔离级别,事务不能重合,什么问题都能解决,只是效率最低。

以上就是mysql的四种事务隔离级别的验证。

原文:https://www.cnblogs.com/alichengxuyuan/p/12519891.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值