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

这篇具有很好参考价值的文章主要介绍了数据库底层运行原理之——事务管理器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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

事务管理器就是今天要介绍的其中一个组件: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 使用锁和鼠标版本控制混合机制。文章来源地址https://www.toymoban.com/news/detail-420949.html

到了这里,关于数据库底层运行原理之——事务管理器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【cfengDB】自己实现数据库第0节 ---整体介绍及事务管理层实现

    LearnProj 本文作为数工底层的项目CfengDB开始篇章,介绍开发缘由和实现思路 cfeng之前对数据库研究不深入,之前只是能够做到基本的SQL查询和基本的慢SQL优化,之前拿到数据库系统工程师证书还是只在业务上对于DB系统使用更深入,但是cfeng基于work的理解,当作为一个优秀的产

    2024年02月16日
    浏览(42)
  • 4、hive的使用示例详解-事务表、视图、物化视图、DDL(数据库、表以及分区)管理详细操作

    1、apache-hive-3.1.2简介及部署(三种部署方式-内嵌模式、本地模式和远程模式)及验证详解 2、hive相关概念详解–架构、读写文件机制、数据存储 3、hive的使用示例详解-建表、数据类型详解、内部外部表、分区表、分桶表 4、hive的使用示例详解-事务表、视图、物化视图、DDL

    2024年02月09日
    浏览(51)
  • 【数据库】事务的隔离级别以及实现原理

    经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗,事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么呢?本文就帮大家梳理一下。 事务,由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。

    2023年04月26日
    浏览(43)
  • Oracle架构_数据库底层原理、机制 (授人以渔)

    目录 系统全局区SGA 高速缓存缓冲区(数据库缓冲区) 日志缓冲区 共享池 其他结构 用户连接进程 用户进程User Process Server Process服务进程 程序全局区PGA Oracle的connect连接和session会话与User Process紧密相关 后台进程 数据库写入进程(DBWn) 检查点(CKPT) 进程监视进程(PMON) 系统监视进程

    2024年01月20日
    浏览(69)
  • 分布式数据库事务故障恢复的原理与实践

    关系数据库中的事务故障恢复并不是一个新问题,自70年代关系数据库诞生之后就一直伴随着数据库技术的发展,并且在分布式数据库的场景下又遇到了一些新的问题。本文将会就事务故障恢复这个问题,分别讲述单机数据库、分布式数据库中遇到的问题和几种典型的解决方

    2024年02月03日
    浏览(41)
  • 客户端读写HBase数据库的运行原理

    1.HBase的特点 HBase是一个数据库,与RDMS相比,有以下特点: ① 它不支持SQL ② 不支持事务 ③ 没有表关系,不支持JOIN ④ 有列族,列族下可以有上百个列 ⑤ 单元格,即列值,可以存储多个版本的值,每个版本都有对应时间戳 ⑥ 行键按照字典序升序排列 ⑦ 元数据 和 数据 分

    2024年02月10日
    浏览(56)
  • 【MySQL数据库原理】在MySQL Workbench界面运行SQL代码——学生管理系统

    在 MySQL Workbench 8.0 中,你可以使用以下步骤新建内容并运行 MySQL 语言代码: 1、打开 MySQL Workbench 并连接到你的 MySQL 数据库服务器。 2、在左侧的导航栏中,展开你的连接以查看数据库。选择你要在其中运行 SQL 代码的数据库。 3、在顶部菜单栏中,点击 “Query”(查询)选项

    2024年02月03日
    浏览(57)
  • 数据仓库与事务管理

    随着大数据时代的到来,数据仓库已成为企业决策和支持业务发展的重要工具。然而,关于数据仓库是否面向事务处理,一直存在争议。本文将围绕这一话题展开讨论,重点阐述数据仓库的特点、优缺点以及面向事务处理的技术和应用。 数据仓库是用于存储、管理和分析大量

    2024年02月11日
    浏览(43)
  • 数据库——事务,事务隔离级别

    什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行。 事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误

    2024年02月11日
    浏览(46)
  • 千云物流- 多数据源事务管理

    Spring只是个容器,因此它并不做任何事务的具体实现。他只是提供了事务管理的接口PlatformTransactionManager,具体内容由就由各个事务管理器来实现。 DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于S

    2024年02月02日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包