数据库底层运行原理之——事务管理器

news2025/1/13 17:30:15

一般所有关系型数据库内部都有自己的事务机制,进程是如何保证每个查询在自己的事务内执行的,通过这篇文章来简单介绍一下。

我们可以理解为数据库是由多种相互交互的组件构成的,数据库一般可以用如下图形来理解:

事务管理器就是今天要介绍的其中一个组件:Transaction manager

在讲事务之前,我们需要理解ACID事务的概念。

一个ACID事务是一个工作单元,它要保证4个属性:

  • 原子性Atomicity): 事务『要么全部完成,要么全部取消』,即使它持续运行10个小时。如果事务崩溃,状态回到事务之前(事务回滚)。
  • 隔离性Isolation): 如果2个事务 A 和 B 同时运行,事务 A 和 B 最终的结果是相同的,不管 A 是结束于 B 之前/之后/运行期间。
  • 持久性Durability): 一旦事务提交(也就是成功执行),不管发生什么(崩溃或者出错),数据要保存在数据库中。
  • 一致性Consistency): 只有合法的数据(依照关系约束和函数约束)能写入数据库,一致性与原子性和隔离性有关。

现代数据库不会使用纯粹的隔离作为默认模式,因为它会带来巨大的性能消耗。SQL一般定义4个隔离级别:

  • 串行化(Serializable,SQLite默认模式):最高级别的隔离。两个同时发生的事务100%隔离,每个事务有自己的『世界』。
  • 可重复读(Repeatable read,MySQL默认模式):每个事务有自己的『世界』,除了一种情况。如果一个事务成功执行并且添加了新数据,这些数据对其他正在执行的事务是可见的。但是如果事务成功修改了一条数据,修改结果对正在运行的事务不可见。所以,事务之间只是在新数据方面突破了隔离,对已存在的数据仍旧隔离。 举个例子,如果事务A运行”SELECT count(1) from TABLE_X” ,然后事务B在 TABLE_X 加入一条新数据并提交,当事务A再运行一次 count(1)结果不会是一样的。 这叫幻读(phantom read)。
  • 读取已提交(Read committed,Oracle、PostgreSQL、SQL Server默认模式):可重复读+新的隔离突破。如果事务A读取了数据D,然后数据D被事务B修改(或删除)并提交,事务A再次读取数据D时数据的变化(或删除)是可见的。 这也叫不可重复读(non-repeatable read)。
  • 读取未提交(Read uncommitted):最低级别的隔离,是读取已提交+新的隔离突破。如果事务A读取了数据D,然后数据D被事务B修改(但并未提交,事务B仍在运行中),事务A再次读取数据D时,数据修改是可见的。如果事务B回滚,那么事务A第二次读取的数据D是无意义的,因为那是事务B所做的从未发生的修改(已经回滚了嘛)。 这也叫脏读(dirty read)。

默认的隔离级别可以由用户/开发者在建立连接时指定,一般mysql默认的隔离级别是 可重复读 ,当然,隔离级别越高的话,对应的效率是越低的。

并发控制

确保隔离性、一致性和原子性的真正问题是对相同数据的写操作(增、更、删):

  • 如果所有事务只是读取数据,它们可以同时工作,不会更改另一个事务的行为。
  • 如果多个事务同时操作同一个数据,可能出现事务A的更改被事务B或者C所覆盖等等。

因此在高并发下要对可能出现的一些问题做 并发控制

最简单的解决办法是依次执行每个事务(即顺序执行),但这样就完全没有伸缩性了,在一个多处理器/多核服务器上只有一个核心在工作,效率很低。

为了解决这个问题,多数数据库使用和/或数据版本控制

悲观锁

原理是:

如果一个事务需要一条数据,它就把数据锁住,如果另一个事务也需要这条数据,它就必须要等第一个事务释放这条数据 这个锁叫排他锁

但是对一个仅仅读取数据的事务使用排他锁非常昂贵,因为这会迫使其它只需要读取相同数据的事务等待。因此就有了另一种锁,共享锁

共享锁是这样的:

如果一个事务只需要读取数据A,它会给数据A加上『共享锁』并读取,如果第二个事务也需要仅仅读取数据A,它会给数据A加上『共享锁』并读取,如果第三个事务需要修改数据A,它会给数据A加上『排他锁』,但是必须等待另外两个事务释放它们的共享锁。

同样的,如果一块数据被加上排他锁,一个只需要读取该数据的事务必须等待排他锁释放才能给该数据加上共享锁。

锁管理器是添加和释放锁的进程,在内部用一个哈希表保存锁信息(关键字是被锁的数据),并且了解每一块数据是:

  • 被哪个事务加的锁
  • 哪个事务在等待数据解锁

死锁

使用锁会导致一种情况,2个事务永远在等待一块数据

如上图所示:

  • 事务A 给 数据1 加上排他锁并且等待获取数据2
  • 事务B 给 数据2 加上排他锁并且等待获取数据1

这叫死锁

在死锁发生时,锁管理器要选择取消(回滚)一个事务,以便消除死锁,这也是一个比较耗时的过程。

哈希表可以看作是个图表(见上文图),图中出现循环就说明有死锁。由于检查循环是昂贵的(所有锁组成的图表是很庞大的),经常会通过简单的途径解决:使用超时设定。如果一个锁在超时时间内没有加上,那事务就进入死锁状态。

事务开始时获取锁,结束时释放锁,这是可以实现纯粹的隔离,但是这种方法会等待所有的锁,大量的时间被浪费了。

更快的方法是两段锁协议(Two-Phase Locking Protocol,由 DB2 和 SQL Server使用),在这里,事务分为两个阶段:

  • 成长阶段:事务可以获得锁,但不能释放锁。
  • 收缩阶段:事务可以释放锁(对于已经处理完而且不会再次处理的数据),但不能获得新锁。

 

这两条简单规则背后的原理是:

  • 释放不再使用的锁,来降低其它事务的等待时间
  • 防止发生这类情况:事务最初获得的数据,在事务开始后被修改,当事务重新读取该数据时发生不一致。

这个规则可以很好地工作,但有个例外:如果修改了一条数据、释放了关联的锁后,事务被取消(回滚),而另一个事务读到了修改后的值,但最后这个值却被回滚。为了避免这个问题,所有独占锁必须在事务结束时释放

数据版本控制是解决这个问题的另一个方法

版本控制是这样的:

  • 每个事务可以在相同时刻修改相同的数据
  • 每个事务有自己的数据拷贝(或者叫版本)
  • 如果2个事务修改相同的数据,只接受一个修改,另一个将被拒绝,相关的事务回滚(或重新运行)

这将提高性能,因为:

  • 读事务不会阻塞写事务
  • 写事务不会阻塞读
  • 没有『臃肿缓慢』的锁管理器带来的额外开销

一些数据库,比如DB2(直到版本 9.7)和 SQL Server(不含快照隔离)仅使用锁机制。其他的像PostgreSQL, MySQL 和 Oracle 使用锁和鼠标版本控制混合机制。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

两种方法,计算带地形起伏的地表面积

很多同学会经常计算占地面积, 就会用到投影面积计算和椭球体面积计算; 还有一些,需要去计算表面积, 也就是带地形起伏的地表面积, 这......咋办呢? 我们来介绍两种方法, 计算下面这个区域的地表面积—— 两种方法各有优势, 大家各取所需 方法一:表面体积工具 这…

【hello Linux】进程优先级

目录 1. 基本概念 2. 查看系统进程:(包括优先级) 2.1 使用命令查看系统进程 2.2 各字段分析 2.3 优先级的修正解释 2.4 使用 top 命令修改优先级 其他概念 Linux🌷 1. 基本概念 进程的优先权( priority)&…

Java版企业电子招投标系统源代码之电子招投标系统建设的重点和未来趋势

项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…

网工神器:PNETLab模拟器踩坑过程(一)

0、前言 由于工作需要,想测试一下SD-WAN,手边既没有测试环境又没有测试设备。突然想到为什么不用模拟器测试。经过我一番操作好像发现了新大陆,没想到模拟器的世界发生了翻天覆地的变化。真是“一日学习一日功,一日不学十日空”。…

【IoT】以一款实际产品为例,来谈谈如何做商业计划分析

本篇内容以笔者早期刚转型做产品时,实际负责的一款产品为例,来谈谈如何做产品的商业计划分析。 首先简单介绍一下这款产品: 这是一款电子便签产品,目的是为了替换纸质便签,增加一些智能化的提醒控制。 该产品通过蓝牙与手机端连接,应用端配置好提醒信息后一键同步至产…

鼠标悬停发光按钮,流转边框

提示&#xff1a;css 动画实现&#xff0c;鼠标悬停发光按钮&#xff0c;流转边框。鼠标border可以旋转 前言 提示&#xff1a;以下是本篇文章的代码内容,供大家参考,相互学习 一、html代码 <!DOCTYPE html> <html><head><meta http-equiv"content…

企业信息化建设该怎么做?方向和手段都在这了

企业信息化建设该怎么做&#xff1f; 如果现在是十年前&#xff0c;我一定会说&#xff0c;做信息化需要寻找熟悉不同编程语言、有经验的程序员。 但是现在&#xff0c;如果不是特别复杂的信息化系统&#xff0c;其实公司完全可以使用零代码平台自主开发&#xff0c;不需要再…

[计算机图形学]光线追踪:加速结构(前瞻预习/复习回顾)

一、前言 上篇我们提到了&#xff0c;如果在光线追踪中&#xff0c;我们真的用每个像素发出的光线&#xff0c;以及在场景中弹射之后的光线与场景中的许多模型的上千万个三角形求交那将是一个非常慢的计算过程&#xff0c;所以&#xff0c;本篇我们将介绍一些加速结构来加速这个…

【FTP服务】

目录 一、FTP服务二、FTP服务器安装配置FTP服务的安装匿名访问开启防火墙设置本地用户修改配置文件 以图形化的格式来写入文件 三、设置白名单&#xff0c;黑名单用户 一、FTP服务 作用: 是用来传输文件的协议 端口: FTP服务器默认使用TCP协议的20、21端口与客户端进行通信 2…

OpenHarmony生态贡献获肯定,华秋践行加速硬件创业初心

4月19日,以“开源正当时,共赢新未来”为主题的开放原子开源基金会OpenHarmony开发者大会2023(以下简称“大会”)成功举办。大会现场,来自开放原子开源基金会和OpenHarmony项目的领导与专家、以及共建单位、行业伙伴和社区开发者们共聚一堂。值得信赖的电子产业一站式服务平台华…

【软件测试】四面成功上岸美团

最后&#xff0c;总结一下个人认为比较重要的知识点&#xff1a;接口自动化测试 &#xff1a;测试框架&#xff0c;多个有关联的接口的用例编写&#xff0c;用例的组织及存储&#xff0c;接口测试的覆盖率&#xff0c;RESTAssured 的封装等。UI 自动化测试 &#xff1a;iOS 和 …

二维码+互联网云技术在中建二局施工项目管理中的应用实践

中建二局&#xff08;全称&#xff1a;中国建筑第二工程局有限公司&#xff09;是世界500强企业—中国建筑股份有限公司的全资子公司&#xff0c;是集房建、基建、核电、火电、风电等多种建设和投资相融合的、国内最具综合实力的大型国有企业集团公司。中建二局具有土木建筑、设…

Jetson Orin Nano下部署 Yolo v5

在网上找了好多关于Jetson Nano部署Yolo v5的帖子&#xff0c;由于每个人的环境和版本都不同&#xff0c;过程也都有所不同&#xff0c;因此在Jetson Orin Nano CLB上安装Yolo v5也有必要记录一下过程&#xff0c;以便后续无脑重装&#xff0c;让我们开始。 由于我这个Jetson …

【IT成神路之我在起点学网络~】

什么是网络&#xff0c;一开始我以为是能刷刷剧&#xff0c;让我看到心仪idol&#xff0c;坐在家中看祖国大好河山就是网络。 长时间浸泡在网络上&#xff0c;不得不让我思索我为什么能看到高清不卡顿的精彩视频。 于是乎……我开始大肆搜索网络的资料内容。 IT嘛&#xff0…

OCR技术大揭秘:纸质文档数字化的新选择

引言 OCR&#xff08;Optical Character Recognition&#xff09;即光学字符识别技术&#xff0c;是一种将纸质或电子文档中的印刷文字转化为可编辑和可搜索的数字文本的技术。随着数字化和信息化的快速发展&#xff0c;OCR 技术逐渐成为处理大量纸质或电子文档的主要手段之一…

【Zblog建站】搭建属于自己的博客网站,并内网穿透实现公网访问

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 想要成为一个合格的技术宅或程序员&#xff0c;自己搭建网站制作网页是绕…

基于Java+Springboot+vue网上商品订单转手系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

机器学习(一)K近邻算法(KNN)原理剖析及python源码

本篇介绍第一个机器学习算法&#xff1a;k-近邻算法&#xff0c;它非常有效而且易于掌握。首先&#xff0c;我们将探讨k-近邻算法&#xff08;KNN&#xff09;的基本理论&#xff0c;以及如何使用距离测量的方法分类物品&#xff1b;其次我们将使用Python从文本文件中导入并解析…

【C++】你知道为什么在写C++代码之前要在开头写上using namespace std吗?

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

如何设计一个高并发系统

目录 如何理解高并发系统 1. 分而治之&#xff0c;横向扩展 2. 微服务拆分&#xff08;系统拆分&#xff09; 3. 分库分表 4. 池化技术 5. 主从分离 6. 使用缓存 7. CDN——加速静态资源访问 8. 消息队列——削锋 9. ElasticSearch 10. 降级熔断 11. 限流 12. 异步…