SQL基础理论篇(十一):事务隔离

文章目录

  • 简介
  • 事务并发时的常见异常
    • 什么是脏读?
    • 什么是不可重复读?
    • 什么是幻读?
  • 事务的常用隔离级别
  • 参考文献

简介

之前我们讲过事务的四大特性,即ACID,分别是原子性、一致性、隔离性和持久性。隔离性就是事务的基本特性之一,可以防止数据库在并发处理时出现数据不一致的情况。

如果我们严格限制每一个事务是串行运行,这就意味着事务之间是相互独立的,但实际生产环境中,这样做是明显不可能的,因为随着用户量的增多,必然会存在大规模并发访问的情况,串行并不可取。于是我们通过设置不同的隔离级别,来换取事务的并发处理能力。

事务并发时的常见异常

首先我们需要了解事务在并发时会出现的一些异常情况,不同的隔离级别会分别解决不同的异常。

事务在并发时容易出现三种异常情况:

  • 脏读,即Dirty Read
  • 不可重复读,即Nonrepeatable Read
  • 幻读,即Phantom Read

事务的隔离级别,主要就是为了解决并发处理时会出现的这三种异常情况。

本小节,我们先介绍一下什么是脏读、不可重复读,和幻读。

什么是脏读?

简单的说,就是事务B读取了事务A尚未提交的数据。其实也叫做"无效数据读出"

假设事务A执行了一行insert,插入了一条新数据,但是它还没有commit,此时事务B对这张数据表进行了访问,就会读出这条新数据,这就是脏读。

至于为什么叫脏读,很好理解。如果在事务B读取了数据表之后,事务A因为其他原因被rollback了,那这条数据会被撤销插入。那么对事务B来讲,它刚刚读取到的,就是表里最终不存在的数据,或者说是无效的数据,所以叫脏读。

解决方法就是把数据库的隔离级别调整到READ_COMMITTED(读提交)。这个之后会讲。

什么是不可重复读?

简单的说,就是在同一事务里,对同一条记录,先后两次读取的结果不一样。

假设事务A需要执行两次select name from heros where id = 1;

第一次执行后返回的结果是"赵云"。

然而在它执行第二次查询之前,事务B被启动,对id=1的记录做了修改,即执行了update heros set name='张翼德' where id=1;,并提交。

那么之后事务A启动第二次查询的时候,返回的结果就是"张飞"。

像这种情况里,同一事务,先后两次查询的结果就会不一样,这就是不可重复读。

如图:

在这里插入图片描述

解决方法是把数据库的隔离级别调整到REPEATABLE_READ。

什么是幻读?

简单的说,就是在同一事务里,相同的查询条件,先后两次查询出的结果集行数不一致

事务A根据条件查询得到了N条数据,此时事务B删除或者增加了M条符合事务A查询条件的数据,并提交,这样当事务A再次按照相同条件查询的时候,会发现返回了N+M条数据,这就是幻读。跟发生了幻觉一样。

幻读跟不可重复读的区别在于,不可重复读是因为对同一条数据的修改,而幻读是因为数据的新增或者删除,即返回的记录数不一样。

事务的常用隔离级别

脏读、不可重复读和幻读,都是SQL-92标准中定义的,同时,92标准中还定义了4种隔离级别来解决这几种异常。

按照解决异常的数量,可以排列出隔离级别的高低,由低到高依次是:

  • 读未提交,即READ_UNCOMMITTED
  • 读已提交,即READ_COMMITTED
  • 可重复读,即REPEATABLE_READ
  • 可串行化,即SERIALIZABLE

这些隔离级别能解决的异常情况如下:

在这里插入图片描述

可以看到,可串行化可以避免所有的异常情况,而读未提交则允许所有异常情况。

读未提交,就是允许读到其他事务未提交的数据,这种情况下没有任何锁的存在,所以无法避免任何异常情况。

读已提交,就是只能读到其他事务已经提交的内容,可以避免脏读的发生,这也是RDBMS中常见的默认隔离级别,如Oracle和SQL Server。如果想进一步避免不可重复读和幻读,那就需要再结合上加锁的SQL。

可重复读,保证一个事务在相同查询条件下两次查询得到的数据结果是一致的,可避免脏读和不可重复读,但无法避免幻读。MySQL默认的隔离级别就是可重复读。

可串行化,将所有事务放在一个队列中串行执行,无法处理并发,所以多数情况下是理想态。

隔离级别越低,意味着数据库的吞吐量可以越大,即并发程度越高,但同时也意味着出现异常问题的可能性会更大。在实际使用过程中,我们需要在并发的性能和正确性上进行权衡,来选择合适的方案。

而事务的隔离级别,在底层是通过锁来实现 + 保证的,每个隔离级别需要的锁,之后会再介绍。

参考文献

  1. 15丨初识事务隔离:隔离的级别有哪些,它们都解决了哪些异常问题?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/239256.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ROBdispatch stage

ROB会跟踪所有pipeline中的指令的状态;一旦ROB中,header指的entry complete了,则该指令可以commit,其architectural state属于visible了;如果header instruction 发生了异常,pipleine需要flush, 在该exception instruc…

Python接口自动化测试 —— Requests库学习

安装&#xff1a; pip install requests 例子&#xff1a; import requests r requests.get(http://www.baidu.com) print r.status_code print type(r) print r.cookies运行程序&#xff0c;得到结果&#xff1a; 运行程序&#xff0c;得到结果&#xff1a; 200 <…

Leetcode—2963.统计好分割方案的数目【困难】

2023每日刷题&#xff08;五十七&#xff09; Leetcode—2963.统计好分割方案的数目 算法思想 参考灵神思路 实现代码 class Solution { public:long long mod 1e97;long long pow(long long x, int cnt) {if(cnt 0) {return 1;}if(cnt 1) {return x % mod;}long long …

css处理 纯英文数据不换行问题 - word-break、word-wrap

问题图 解决 添加 css 样式 word-break: break-all;补充 还有一个 word-wrap 样式&#xff0c;可以看下 参考 &#xff1a; word-wrap: normal 只在允许的断字点换行&#xff08;浏览器保持默认处理&#xff09;。word-wrap: break-word 在长单词或 URL 地址内部进行换行。

书-选择排序法P156

#include<stdio.h> int main(){int b[5]{8,2,6,3,7};int i , j ,k ;for(i0;i<4;i){for(ji1;j<5;j)if(b[i]<b[j]){kb[i];b[i]b[j];b[j]k;} }for(i0;i<5;i)printf("%d ",b[i]); return 0; }选择排序&#xff1a;就是自己跟下一个比较&#xff0c;然后…

Android studio 无法查看源码

Android studio 查看源码时提示 Decompiled .class file,bytecode version:52.0(java 8) 1、检查 buildToolsVersion 2、检查相关资源文件

SPRD Android 13 下拉状态栏菜单添加静音快捷键简单记录

SPRD Android 13 下拉状态栏菜单添加静音快捷键简单记录 需要修改文件具体修改补丁吐槽需要修改文件 frameworks/base/packages/SystemUI/res/values/config.xml frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java frameworks/base…

1844_高边驱动以及低边驱动的选择

Grey 全部学习内容汇总&#xff1a;GitHub - GreyZhang/g_hardware_basic: You should learn some hardware design knowledge in case hardware engineer would ask you to prove your software is right when their hardware design is wrong! 1844_高边驱动以及低边驱动的…

mmpi量表在各企事业单位 入职体检中的应用

mmpi量表主要应用在医院精神科门诊中&#xff0c;用来检测筛查精神类疾病&#xff0c;比如&#xff1a;焦虑抑郁&#xff0c;疑病妄想强迫性、精神分裂、精神病态、社会内向性、癔症&#xff0c;精神衰弱&#xff0c;躁狂等等。 民航&#xff0c;司法&#xff0c;军警&#xf…

创建第一个SpringBoot项目

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 循序渐进学SpringBoot ✨特色专栏&…

点评项目——好友关注模块

2023.12.12 本章实现好友关注模块&#xff0c;包含以下功能的实现&#xff1a;关注与取关、共同关注、关注推送。 关注与取关 当点击某个用户的主页时&#xff0c;会调用如下接口&#xff1a; 该接口是用来判断是否已经关注该用户&#xff0c;最后一个参数是该用户的i…

1,使用IDLE开启我们第一个Python程序

前面我们已经安装好了Python&#xff0c;安装了Python后&#xff0c;他会自动帮我们安装一个IDLE。IDLE是一个Python自带的非常简洁的集成开发环境&#xff08;IDE&#xff09;。他是一个Python Shell&#xff0c;我们可以利用Python Shell与Python交互。下面我们就利用IDLE开发…

如何学习网络安全

我们应该怎么学习网络安全 首先&#xff0c;必须&#xff08;时刻&#xff09;意识到你是在学习一门可以说是最难的课程&#xff0c;是网络专业领域的顶尖课程&#xff0c;不是什么人、随随便便就能学好的。不然&#xff0c;大家都是黑客&#xff0c;也就没有黑客和网络安全的概…

【玩转TableAgent数据智能分析】TableAgent全功能详解及多领域数据分析实践(中)不同领域数据分析实践

3 电影点评数据分析实践 利用本身自带的电影点评数据&#xff0c;来具体看一下TableAgent的分析能力&#xff0c;选择电影点评数据&#xff0c;智能体会自动导入该数据DMSC20000.csv&#xff0c;大小为3.3 MB。在数据信息展示区&#xff0c;就会显示出该数据&#xff0c;并提供…

C/C++,图算法——Dinic最大流量算法

1 文本格式 // C implementation of Dinics Algorithm #include<bits/stdc.h> using namespace std; // A structure to represent a edge between // two vertex struct Edge { int v; // Vertex v (or "to" vertex) // of a directed edge u…

微服务实战系列之通信

前言 掰个指头数一数&#xff0c;博主的“微服务实战系列”从无到有&#xff0c;从零走到了十五。如果比作时钟&#xff0c;刚好走过了一刻度。 当初为什么要做这个系列&#xff0c;博主想了又想&#xff0c;私以为作为当下软件领域的几个“hot spot”之一&#xff0c;又乘着…

urllib 的 get 请求和 post 请求(二)

目录 一、爬取网页、图片视频 二、请求对象的定制 三、get请求的urlencode方法 四、post 请求英文翻译 一、爬取网页、图片视频 目标&#xff1a;下载数据 知识点&#xff1a;urllib.request.urlretrieve()下载 使用urllib下载网页、图片和视频 下载网页&#xff1a; #…

六、ZGC深度剖析

一、引言 对于Java 程序员来说&#xff0c;JVM 帮助我们做了很多事情。 JVM是虚拟机&#xff0c;能够识别字节码&#xff0c;就是class文件或者你打包的jar文件&#xff0c;运行在操作系统上。 JVM帮我们实现了跨平台&#xff0c;你只需要编译一次&#xff0c;就可以在不同的…

traj_dist 笔记 源代码解析(python部分)

1distance.py 1.1 METRIC_DIC 不同实现方法对应的函数路径 1.2 sspd 功能&#xff1a; 计算轨迹 traj_1 和 traj_2 之间的对称化段路径距离。 参数&#xff1a; traj_1&#xff1a;一个二维 numpy 数组&#xff0c;代表第一个轨迹。traj_2&#xff1a;一个二维 numpy 数组…

FreeRTOS的三处栈空间设置分析

1、汇编启动代码中设置栈 这个栈空间只有300字节&#xff0c;是用于汇编启动代码早期&#xff0c;以及调用C语言的main函数&#xff08;创建任务等&#xff09;在创建好任务&#xff0c;启动调取器后&#xff0c;这个栈空间就被抛弃掉&#xff0c;后续不会使用到等调度器开启后…