MySQL事务隔离级别

事务并发导致的问题是数据库需要重点解决的问题,关于事务处理的技术都已经非常成熟了,四种隔离级别再加上一个快照是所有数据库通行的解决方案,各种数据 库只是在细节上略有不同而已。MySQL支持多种存储引擎,每种存储引擎各有特点,MyISAM速度较快,但是其不支持事务处理,并发时能控制的粒度太 粗。InnoDB是一个非常好的存储引擎,它已经被Oracle收购了,Oracle这几年实在疯狂,InnoDB和Berkeley DB都被其纳入囊中,这次MySQL都未能幸免。Linux版的MySQL默认使用的存储引擎是MyISAM,而Windows版则使用InnoDB。下 面的讨论都是使用InnoDB的表。MySQL默认的隔离级别是可重复读。

mysql> show variables like '%iso%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
脏读,不可重复读,幻读是事务并发导致的几个主要的问题,可重复读是用来解决不可重复读的问题,但是MySQL的可重复读级别似乎有点神奇,它可以避免 幻读的。如果使用快照技术的话,可以一次解决上面所有的问题,不知道InnoDB是怎样做的。
首先测试可重读隔离级别的行为。
1、创建如下所示的表,注意要使用InnoDB引擎:
mysql> show create table innodb \G
*************************** 1. row ***************************
Table: innodb
Create Table: CREATE TABLE `innodb` (
`name` char(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
2、开启两个客户端,分别对其关闭自动提交。
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.00 sec)
mysql> set autocommit=0
-> ;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set (0.00 sec)
3、插入一条要用的测试记录
mysql> insert into innodb values('fzj', 25);
Query OK, 1 row affected (0.00 sec)
mysql> select * from innodb;
+------+------+
| name | age |
+------+------+
| fzj | 25 |
+------+------+
1 row in set (0.00 sec)
4、开始测试,两个客户端分别用红色和蓝色区别,给它们取个名字分别为A和B吧。
1>解决不可重复读问题
mysql> start transaction;
Query OK, 0 rows affected (0.05 sec)

mysql> update innodb set age=age+5 where name='fzj';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from innodb;
+------+------+
| name | age |
+------+------+
| fzj | 30 |
+------+------+
1 row in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from innodb where name='fzj';
+------+------+
| name | age |
+------+------+
| fzj | 25 |
+------+------+
1 row in set (0.00 sec)
此处可见,B事务避免了脏读。
mysql> commit
-> ;
Query OK, 0 rows affected (0.04 sec)

mysql> select * from innodb where name='fzj';
+------+------+
| name | age |
+------+------+
| fzj | 25 |
+------+------+
1 row in set (0.00 sec)
即便是A事务提交了,B事务查询的结果仍然不受干扰,这是可重复读隔离级别的典型特性。可是如果 B事务也要更新同一条记录怎么办?基于这个数字会导致A事务更新的丢失。
mysql> update innodb set age=age+5 where name='fzj';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from innodb where name='fzj';
+------+------+
| name | age |
+------+------+
| fzj | 35 |
+------+------+
1 row in set (0.00 sec)
可见A事务的更新并没有丢失。如果在A事务未提交之前,B事务更新同一条记录会导致B事务被阻塞,update需要对相应行加上行锁,这种排他 锁是独占性的。
2>解决幻读问题
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into innodb values('ecy', 25);
Query OK, 1 row affected (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.04 sec)

mysql> select count(*) from innodb;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.02 sec)
mysql> commit
-> ;
Query OK, 0 rows affected (0.05 sec)

mysql> select count(*) from innodb;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
可见A事务成功地插入了一条记录,因为 它没有同B事务竞争锁,所以A事务插入记录和B事务更新记录可以同时进行,可是A事务提交之后并没有导致B事务幻读,MySQL的可重复读隔离级别确实能 避免幻读。

3>serializable隔离级别
serializable隔离级别是最高的隔离级别,一个事务中的查询语句会给相应的行加上排他锁,直到事务结束。
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update innodb set age=age+6 where name='fzj';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from innodb where name='fzj';
B事务此时会被阻塞,因为A事务要跟新'fzj'这一行,因此给这行加上了排它锁,B事务再将给 其加上共享锁将会失败。使用A事务commit之后,B事务才会往下执行(我发现让我吃惊的行为,在B事务中即使查询name='ecy'这行,B事务也 会被阻塞,难道使用了表锁定??)。比较REPEATABLE-READ隔离级别可以发现,在可重复读隔离级别不会给查询语句加上共享锁,如果需要的话可 以显示地使用select ... lock in share mode和select ... for update分别加上共享锁和排他锁。
  • 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、付费专栏及课程。

余额充值