数据库事务隔离级别
前几天项目上合作公司的系统出现了一次死锁,突然想到由于近几年开发设计的系统并发用户比较少,很久没有碰到过死锁了,因此对死锁的概念也比较生疏了,需要温习一下。
事务
先从最基本的概念开始,事务、及其ACID特性。
事务的概念就用一句话概括:事务中的SQL语句要么全部执行成功,要么全部执行失败。
Atomicity:原子性,一个事务必须被视为不可分割的工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。对于一个事务来说,不能只执行其中的一部分操作,这就是事务的原子性。
Consistency:一致性,事务可以确保数据总是从一个一致性状态转换到另一个一致性状态。
Isolation:隔离性,事务隔离性的目的是要确保一个事务所做的修改在最终提交之前,对其他事务是不可见的。这一点其实是很难做到的,所以才有了iso level,隔离级别的概念。
Durability:持久性,一旦事务提交,修改就会永久保存在数据库中。
隔离级别
SQL标准定义了四种隔离级别:
READ UNCOMMITTED(未提交读)
事务中的修改即使没有提交,其他事务中也是能看见的。事务能够读取未提交数据也被称之为“脏读”(dirty read)。这个级别会导致很多问题,从性能上来说,READ UNCOMMITTED不对比其他级别好太多。但却缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少使用。
*** READ COMMITTED(提交读) ***
大部分数据库(SQL Server/Oracle等)默认的隔离级别,但Mysql不是。一个事务开始后,只能看到其他事务已经提交的修改。READ COMMITTED避免了脏读,但是READ COMMITTED不可重复读(nonrepeatable read),因为在一个事务中两次执行同样的查询,可能会读到不一样的结果。
REPEATABLE READ(可重复读)
可重复读确保了在一个事务中多次读取同样记录的结果是一致的。但是在理论上REPEATABLE READ还是无法解决另外一个幻读(phantom read)的问题。幻读指的是某个事务在读取某个范围内的记录时,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围内的数据时,会产生幻行(phantom row)。InnoDB和XtraDB存储引擎通过引入MVCC解决了幻读问题。
可重复读是MySql默认的隔离级别。
SERIALIZABLE(串行化)
最高隔离级别,通过强制事务串行执行避免幻读问题。简单来说RERIALIZABLE会在读取的每一行数据上加锁,所以可能会导致大量的超时和锁争夺问题,实际应用中很少用这个隔离级别。

死锁
死锁指的是两个或多个事务在统一资源上的相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。
当多个事务试图以不同顺序锁定资源时,就可能产生死锁,多个事务同时锁定同一个资源时,也可能产生死锁。
比如,事务一:
start transaction;
update stock set price=1.2 where id=3;
update stock set price=1.5 where id=4;
commit;
事务二:
start transaction;
update stock set price=1.2 where id=4;
update stock set price=1.5 where id=3;
commit;
如果事务一执行了第一条update语句、锁定了第一条数据、事务二也执行了第一条update语句、锁定了第一条数据,此时两个事务准备执行第二条语句是发现已经被对方锁定,彼此等待对方释放锁资源、同时又持有对方等待的锁资源,这样就陷入了死循环,造成死锁。
死锁发生后必须有第三方介入才可能解除。比如大部分的数据库都设置了等待的timeout时长,超过该时长后事务会主动放弃等待(InnoDB引擎将持有最少行级排它锁的事务回滚)、rollback事务。
死锁是事务性数据库系统中不可避免的现象,我们可以认为死锁其实是数据一致性的一种保护性措施,但是我们在设计应用的时候,还是要在充分理解死锁底层逻辑的前提下,尽可能避免死锁的发生。
MVCC
MVCC是multi-version concurrency control的缩写,意思是多版本并发控制。多版本并发控制是尽可能避免加锁操作而实现数据库的ACID,因此开销更低。
MVCC是通过保存数据在某一个时间点的快照来实现的,也就是说,不管执行多长时间,每个事务看到的数据是一致的。根据事务开始时间的不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。
MVCC没有统一的实现标准,不同存储引擎的MVCC实现是不同的。
InnoDB的MVCC实现的简化版行为:
InnoDB的每行记录后面保存两个隐藏的列,一个保存行的创建时间、一个保存行的删除时间。但是实际记录的并不是时间,而是版本号。
没开始一个新的事务,版本号会自动递增,事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行版本号作比较。
在REPEATABLE READ隔离级别下:
SELECT操作,InnoDB会以下两个条件检查每行记录:
- 只查找版本早于当前事务版本号的数据行(也就是,行的系统版本号小于等于事务的系统版本号),这样可以确保事务读取的数据行,要么是事务开始前已经存在的,要么是当前事务插入或修改过的。
- 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读到到的行,在事务开始之前未删除。
INSERT操作:
为插入的每一行保存当前事务的系统版本号作为行版本号。
DELETE操作:
为删除的每一行保存当前事务的系统版本号作为行的删除标识。
UPDATE操作:
插入一条新纪录,保存当前事务版本号作为行版本号,同时保存当前事务版本号到原有行作为删除标识。
MVCC机制可以确保在大多数情况下的读操作都不需要加锁,使得读数据操作很简单、性能更好,并且能确保读取到符合标准的数据。不足之处是每行记录都需要额外的空间,并且要做更多的检查工作,以及一些额外的维护工作。
MVCC只在REPEATABLE READ和READ COMMITTED 两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容。
相关文章:
数据库事务隔离级别
前几天项目上合作公司的系统出现了一次死锁,突然想到由于近几年开发设计的系统并发用户比较少,很久没有碰到过死锁了,因此对死锁的概念也比较生疏了,需要温习一下。 事务 先从最基本的概念开始,事务、及其ACID特性。…...
Pytest 记录日志输出到控制台和写入文件
目录 自定义日志记录器和内置的日志记录器 项目代码 项目目录树 自定义日志记录器 函数源代码 pytest中定义和覆盖日志记录信息 使用cli定义Logging 使用pytest.ini定义Logging 修改单个测试级别的日志 日志输出的重要性不言而喻,不仅可以观测执行过程&…...
LINUX网络FTP服务
一、FTP服务 FTP服务:file transfer protocol :文件传输协议。在网络上进行双向传输,也是一个应用程序。不同的操作系统有不同的FTP软件,但使用的协议是一样的。 FTP协议基于TCP协议,有两个端口,即20和21。 20端口&…...
10 C++11
10 C11 1、类型推导1.1 auto关键字1.2 auto类型推断本质 2、类型计算2.1 类型计算分类2.2 类型计算的四种规则2.3 返回值类型计算 3、列表初始化4、Lambda表达式4.1 前置知识4.2 Lambda表达式4.3 捕获表 5、右值引用5.1 概念5.2 左值引用和右值引用 6、移动语义 1、类型推导 1…...
java的封装
为什么要封装?在java的面向对象的思想中,封装是指将类的实现细节包装,隐藏起来的方法。封装可以防止本类的代码和数据被外部定义的代码随机访问。 如何进行封装? 在定义一个类时,将类中的属性私有化,即使…...
为什么选择海外服务器?
如何选择跨境电商服务器:详细指南 选择合适的服务器是跨境电商企业成功的基础。服务器的性能和稳定性直接影响着网站的访问速度、用户体验和安全性,进而影响着企业的销量和利润。那么,跨境电商企业该如何选择服务器呢? 1. 确定目…...
k8s+springcloud+nacos部署配置
1 k8s 部署nacos-2.1.2配置k8s-nacos-statefulSet.yaml文件 apiVersion: v1 kind: Service metadata:name: nacos-headlessnamespace: rz-dtlabels:app: nacosannotations:service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec:# 3个端口打开&…...
梯度提升决策树(GBDT)
GBDT(Gradient Boosting Decision Tree),全名叫梯度提升决策树,是一种迭代的决策树算法,又叫 MART(Multiple Additive Regression Tree),它通过构造一组弱的学习器(树&am…...
数据结构之B树的原理与业务场景
B树是一种自平衡的树形数据结构,它能够保持数据有序,并且可以高效地进行查找、顺序访问、插入和删除操作。B树的设计是为了优化磁盘I/O操作,因为它可以减少磁盘访问次数,这在数据库和文件系统中非常有用。 1. B树的原理 节点的出…...
【Android面试八股文】你能说一说线程池管理线程的原理吗?
面试官(Interviewer): 欢迎参加面试,今天我们会讨论一些关于 Java 线程池管理的问题。你能给我解释一下 ThreadPoolExecutor 是如何管理线程的吗? 候选人(Candidate): 当然可以,ThreadPoolExecutor 是 Java 中用于创建和管理线程池的核心类。它通过一组核心参数来控制线…...
springer 在线投稿编译踩坑
springer投稿,在线编译踩坑总结 注意: 有的期刊需要双栏,而预定义的模板中可能为单栏,需要增加iicol选项。 例如: \documentclass[sn-mathphys-num]{sn-jnl}% —>\documentclass[sn-mathphys-num, iicol]{sn-jnl}…...
固态硬盘的指标
固态硬盘的指标主要包括以下几个方面: 接口类型:这是固态硬盘与外部设备连接的方式,常见的接口类型有SATA、PCIe和NVMe等。不同的接口类型决定了固态硬盘的传输速度和性能。例如,PCIe接口的固态硬盘通常比SATA接口的固态硬盘具有…...
mysql 分组后每个取最新的一条记录
在MySQL中,若要从一个分组中获取每组的最新一条记录(通常基于时间戳或其他递增的列),可以使用子查询或者窗口函数(如果MySQL版本支持)。 以下是两种不同的实现方法: 方法1: 使用子查询和LIMIT…...
Java语法和基本结构介绍
Java语法和基本结构是Java编程的基础,它决定了Java代码的书写方式和程序的结构。以下是Java语法和基本结构的一些关键点: 1.标识符和关键字:Java中的标识符是用来标识变量、函数、类或其他用户自定义元素的名称。关键字是预留的标识符&#x…...
TDengine 3.3.0.0 引入图形化管理工具、复合主键等 13 项关键更新
在涛思数据研发团队的努力下,TDengine 3.3.0.0 版本终于和大家见面了。这一版本中,我们引入了多项革新功能和性能优化,力求在为用户提供极致体验的同时,不断推动技术的前沿。 此次更新不仅针对开源社区版本,进行了一系…...
C++基础之红黑树
二叉搜索树 二叉搜索树(Binary Search Tree,BST)是一种二叉树,具有以下性质: 左子树节点值小于根节点值:对于树中的每个节点 x,其左子树中所有节点的值都小于 x 的值。右子树节点值大于根节点值…...
ClickHouse数据库对比、适用场景与入门指南
本文全面对比了ClickHouse与其他数据库(如StarRocks、HBase、MySQL、Hive、Elasticsearch等)的性能、功能、适用场景,并提供了ClickHouse的教学入门指南,旨在帮助读者选择合适的数据库产品并快速掌握ClickHouse的使用。 文章目录 …...
举例说明 如何通过SparkUI和日志定位任务莫名失败?
有一个Task OOM: 通过概览信息,发现Stage 10的Task 36失败了4次导致Job失败。概览信息中显示最后一次失败的退出代码(exit code)是143,意味着发生了内存溢出(OOM,即Out of Memory)。…...
Vue前端通过Axios的post方式传输数据,后端为什么一直接收的值是null?
沃靠!这个细节太细了,搞了我两个多小时才找到这个bug。 一、 首先官方文档给我的post请求的例子是这样的: axios.post(/user, {firstName: Fred,lastName: Flintstone}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);})…...
外链建设如何进行?
理解dofollow和nofollow链接,所谓dofollow链接,就是可以传递权重到你的网站的链接,这种链接对你的网站排名非常有帮助,这种链接可以推动你的网站在搜索结果中的位置向上爬,但一个网站全是这种有用的链接,反…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
