事务隔离级别与脏读、不可重复读、幻读

开始在学习这几个概念的时候,发现不仅是身边,而且网上有很多人都把这些概念搞混淆了,特别是幻读.又由于这些都是一些概念性的东西,所以我就去查了一下官方文档:详见: MySQL 事务隔离级别相关官方文档翻译

为了测试我们先准备一个表并插入几条数据:
drop table if exists t;
create table t(
id int primary key auto_increment,
name varchar(10),
sal decimal(10,2)
);
insert into t(name,sal) values(‘a’,100);
insert into t(name,sal) values(‘b’,200);
insert into t(name,sal) values(‘c’,300);
insert into t(name,sal) values(‘d’,400);
insert into t(name,sal) values(‘e’,500);

查看当前隔离级别:

show variables like ‘tx%’;

1.脏读 : 读取了未被提交的数据
测试脏读与READ-UNCOMMITTED
set tx_isolation=’READ-UNCOMMITTED’;
事务A:
start transaction;
update t set sal=sal*2;
insert into t(name,sal) values (‘f’,600);
delete from t where id=1; – 不commit.

rollback;


set tx_isolation=’READ-UNCOMMITTED’;
事务B:
start transaction;
select * from t; – 在事务A之前查询

select * from t; – 在事务A增删改之后查询,查询到了事务A未提交的数据:发生了脏读

rollback;

2.不可重复读(Unrepeatable Read): 一个事务范围内两个相同的查询却返回了不同数据
测试不可重复读与READ-COMMITTED
set tx_isolation=’READ-COMMITTED’;
事务A:
start transaction;
update t set sal=sal*2;
insert into t(name,sal) values (‘f’,600);
delete from t where id=1;

commit; – 在事务B第二次查询之后
select * from t; – 用于和事务B中对比


set tx_isolation=’READ-COMMITTED’;
事务B:
start transaction;
select * from t; – 在事务A之前查询

select * from t; – 在事务A增删改但未提交之后查询,已经看不到被事务A改动的数据:避免了脏读.

select * from t; – 在事务A提交之后查询,可以看到被A改动的数据:发生了不可重复读.

rollback;

重建表格

MySQL文档中:MySQL 5.7 Reference Manual :: 14.5.4 Phantom Rows
The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.
幻影行的解释:如果一个SELECT被执行了两次,但是第二次返回了一个第一次没有返回的行,那么该行就称为“幻影”行.

MySQL文档中:MySQL 5.7 Reference Manual :: MySQL Glossary(节选)
A row that appears in the result set of a query, but not in the result set of an earlier query.
This occurrence is known as a phantom read.
在查询一组结果中出现的行,但不是在之前查询的一组结果中出现的行。
这种现象被称为“幻读”。

3.幻读(phantom read): 一个事务范围内对于一组的查询看到了原本没有的行
测试幻读与REPEATABLE-READ
set tx_isolation=’REPEATABLE-READ’;
事务A:
start transaction;
insert into t(name,sal) values (‘f’,600);
commit;


set tx_isolation=’REPEATABLE-READ’;
事务B:
start transaction;
select * from t; – 在事务A之前,查询出一组数据.

select * from t; – 在事务A提交之后,查询到的数据仍然是上一次查询的数据:避免了不可重复读.

update t set sal=sal*2; – 查询之后进行修改.

select * from t; – 在本事务中对全表进行修改之后查询,发现多了一行name=f
我们的预期结果本来是在本事务内每次查询都能看到与第一次查询一样的结果,但是
现在查询发现了原本没有的行:发生了幻读.
rollback;

重点:在同一事务内查询(一些人把幻读误解为:在事务A中对全表数据进行修改 事务B插入一行数据,结束事务后查询到了一行未被修改的数据.)

重建表格

4.测试SERIALIZABLE

set tx_isolation=’SERIALIZABLE’;
事务A:
start transaction;
select * from t;

commit; – 在事务B进行修改之后提交


set tx_isolation=’SERIALIZABLE’;
事务B:
start transaction;
select * from t;
update t set sal=sal*2 where id=1; – 被阻塞
– 当事务A提交之后(事务结束),修改成功.
rollback;


事务A:
start transaction;

insert into t(name,sal) values (‘f’,600); – 在事务B查询之后插入,被阻塞

事务B:
start transaction;
select * from t;

update t set sal=sal*2; – 在事务A进行插入(被阻塞)之后修改数据.

select * from t; – 未看到被事务A插入的数据(事务A中的插入操作还未执行):避免了幻读.


REPEATABLE-READ级别下
易混淆点:在REPEATABLE-READ级别下的查询结果是进行第一次查询时固定的,而不是开启事务时.
因为RR中的consistent read是以事务中第一个select语句执行的时间点作为snapshot建立的时间点的.(详见文档中consistent read)
测试:
事务A:
start transaction; – 开启事务A时事务B还未插入数据.

select * from t; – 在事务B进行插入操作并提交之后.

select * from t; – 在事务C进行插入操作并提交后.

事务B:
start transaction;
insert into t(name,sal) values (‘f’,600);
commit;

事务C:
start transaction;
insert into t(name,sal) values (‘g’,700);
commit;

结果:事务A的查询能够查询到被事务B插入的数据.但是看不到被事务C插入的数据.
结论:在RR模式下查询的快照是根据第一个select是保存的.

==================================================================================================
以下是个人的其它思考
在SERIALIZABLE下
事务A只对表进行查询,事务B只能对表进行查询,想进行增删改操作都会被阻塞.
在这里当B对表也进行查询之后,事务A再对数据进行增删改操作都会被阻塞,也就是说这个锁定,是根据最后一个对表进行查询的事务来决定的.

SERIALIZABLE下
*都是行级锁
事务A:
start transaction;
select * from t where id=1;
事务B:
start transaction;
update t set sal=sal*2 where id=2; – 在事务A查询之后,不被阻塞.
update t set sal=sal*2 where id=1; – 在事务A查询之后,被阻塞.

事务A对数据进行增删改操作(未commit),被A动过的数据,事务B想进行增删改查会被阻塞,但是事务A未修改到的数据,事务B是可以进行修改删除的;

事务A对表内数据进行查询时,会对那些数据加一个锁,被锁住的数据在别的事务中只能够进行查询.
事务A对表内数据进行增删改时,加的锁,会使这些数据在别的事务中的增删改查都阻塞.

七个名词:三个现象+四个限制级别
三个现象:
脏读:查询到了另一个事务更新但未提交的数据,不符合数据库设计的ACID原则
不可重复读:在一个事务中一次查询读取到了与上一次一样的查询不同的数据.
幻读:一个事务范围内对于一组的查询看到了原本没有的行.
四个限制级别:
READ UNCOMMITTED(基本不用):性能最高,可以读取到别的事务更新但未提交的数据.
READ COMMITTED:不能从其他事务中看到未提交的数据,但是它们可以看到在当前事务启动后由另一个事务提交的数据.避免了脏读.
REPEATABLE READ(MySQL默认):在事务中进行了第一次查询后,之后每次相同的查询查询的结果都是一样的.避免了不可重复读与脏读.
但是另一事务对表进行插入并提交后,本事务对全表进行修改,会发现幻影行.也就是发生了幻读.
SERIALIZABLE(基本不用):性能最低,保护性最高,通过一系列限制,避免了脏读、不可重复读、幻读操作.

现象与限制级别的关系是:不同限制级别通过一系列不同的限制行为,避免了不同的现象产生.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值