iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >怎么浅析数据库并发控制
  • 392
分享到

怎么浅析数据库并发控制

2024-04-02 19:04:59 392人浏览 八月长安
摘要

怎么浅析数据库并发控制,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。数据库事务隔离发展标准一文中,从标准制定的角度介绍了数据库的隔离级别,介绍

怎么浅析数据库并发控制,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

数据库事务隔离发展标准一文中,从标准制定的角度介绍了数据库的隔离级别,介绍了Read Uncommitted、Read Committed、Repeatable Read、Serializable等隔离级别的定义。下面就来看看究竟有哪些常见的实现事务隔离的机制,称之为并发控制(Concurrency Control)。

原理

所谓并发控制,就是保证并发执行的事务在某一隔离级别上的正确执行的机制。需要指出的是并发控制由数据库的调度器负责,事务本身并不感知,如下图所示,Scheduler将多个事务的读写请求,排列为合法的序列,使之依次执行:

怎么浅析数据库并发控制

这个过程中,对可能破坏数据正确性的冲突事务,调度器可能选择下面两种处理方式:

  • Delay:延迟某个事务的执行到合法的时刻

  • Abort:直接放弃事务的提交,并回滚该事务可能造成的影响

可以看出Abort比Delay带来更高的成本,接下来我们就介绍不同的并发控制机制在不同情况下的处理方式。

分类

怎么浅析数据库并发控制

如上图所示,这里从横纵两个维度,对常见的并发控制机制进行分类:

1. 乐观程度

不同的实现机制,基于不同的对发生冲突概率的假设,悲观方式认为只要两个事务访问相同的数据库对象,就一定会发生冲突,因而应该尽早阻止;而乐观的方式认为,冲突发生的概率不大,因此会延后处理冲突的时机。如上图横坐标所示,乐观程度从左向右增高:

  • 基于Lock:最悲观的实现,需要在操作开始前,甚至是事务开始前,对要访问的数据库对象加,对冲突操作Delay;

  • 基于Timestamp:乐观的实现,每个事务在开始时获得全局递增的时间戳,期望按照开始时的时间戳依次执行,在操作数据库对象时检查冲突并选择Delay或者Abort;

  • 基于Validation:更乐观的实现,仅在Commit前进行Validate,对冲突的事务Abort

可以看出,不同乐观程度的机制本质的区别在于,检查或预判冲突的时机,Lock在事务开始时,Timestamp在操作进行时,而Validation在最终Commit前。相对于悲观的方式,乐观机制可以获得更高的并发度,而一旦冲突发生,Abort事务也会比Delay带来更大的开销。

2. 单版本 VS 多版本

如上图纵坐标所示,相同的乐观程度下,还存在多版本的实现。所谓多版本,就是在每次需要对数据库对象修改时,生成新的数据版本,每个对象的多个版本共存。读请求可以直接访问对应版本的数据,从而避免读写事务和只读事务的相互阻塞。当然多版本也会带来对不同版本的维护成本,如需要垃圾回收机制来释放不被任何事物可见的版本。

需要指出的是这些并发控制机制并不与具体的隔离级别绑定,通过冲突判断的不同规则,可以实现不同强度的隔离级别,下面基于Serializable具体介绍每种机制的实现方式。

基于Lock

基于Lock实现的Scheduler需要在事务访问数据前加上必要的锁保护,为了提高并发,会根据实际访问情况分配不同模式的锁,常见的有读写锁,更新锁等。最简单地,需要长期持有锁到事务结束,为了尽可能的在保证正确性的基础上提高并行度,数据库中常用的加锁方式称为两阶段锁(2PL),Growing阶段可以申请加锁,Shrinking阶段只能释放,即在第一次释放锁之后不能再有任何加锁请求。需要注意的是2PL并不能解决死锁的问题,因此还需要有死锁检测及处理的机制,通常是选择死锁的事务进行Abort。

怎么浅析数据库并发控制

Scheduler对冲突的判断还需要配合Lock Table,如下图所示是一个可能得Lock Table信息示意,每一个被访问的数据库对象都会在Lock Table中有对应的表项,其中记录了当前最高的持有锁的模式、是否有事务在Delay、以及持有或等待对应锁的事务链表;同时对链表中的每个事务记录其事务ID,请求锁的模式以及是否已经持有该锁。Scheduler会在加锁请求到来时,通过查找Lock Table判断能否加锁或是Delay,如果Delay需要插入到链表中。对应的当事务Commit或Abort后需要对其持有的锁进行释放,并按照不同的策略唤醒等待队列中Delay的事务。

怎么浅析数据库并发控制

基于Timestamp

基于Timestamp的Scheduler会在事务开始时候分配一个全局自增的Timestamp,这个Timestamp通常由物理时间戳或系统维护的自增id产生,用于区分事务开始的先后。同时,每个数据库对象需要增加一些额外的信息,这些信息会由对应的事务在访问后更新,包括:

  • RT(X): 最大的读事务的Timestamp

  • WT(X): 最大的写事务的Timestamp

  • C(X): 最新修改的事务是否已经提交

基于Timestamp假设开始时Timestamp的顺序就是事务执行的顺序,当事务访问数据库对象时,通过对比事务自己的Timestamp和该对象的信息,可以发现与这种与开始顺序不一致的情况,并作出应对:

  • Read Late:比自己Timestamp晚的事务在自己想要Read之前对该数据进行了写入,并修改了WT(X),此时会Read不一致的数据。

  • Write Late: 比自己Timestamp晚的事务在自己想要Write之前读取了该数据,并修改了RT(X),如果继续写入会导致对方读到不一致数据。

这两种情况都是由于实际访问数据的顺序与开始顺序不同导致的,Scheduler需要对冲突的事务进行Abort。

  • Read Dirty:通过对比C(X),可以发现是否看到的是已经Commit的数据,如果需要保证Read Commit,则需要Delay事务到对方Commit之后再进行提交。

基于Validation(OCC)

基于Validation的方式,有时也称为Optimistic Concurrency Control(OCC),大概是因为它比基于Timestamp的方式要更加的乐观,将冲突检测推迟到Commit前才进行。不同于Timestamp方式记录每个对象的读写时间,Validation的方式记录的是每个事物的读写操作集合。并将事物划分为三个阶段:

  • Read阶段:从数据库中读取数据并在私有空间完成写操作,这个时候其实并没有实际写入数据库。维护当前事务的读写集合,RS、WS;

  • Validate阶段:对比当前事务与其他有时间重叠的事务的读写集合,判断能否提交;

  • Write阶段:若Validate成功,进入Write阶段,这里才真正写入数据库。

怎么浅析数据库并发控制

同时,Scheduler会记录每个事务的开始时间START(T),验证时间VAL(T),完成写入时间FIN(T),基于Validataion的方式假设事务Validation的顺序就是事务执行的顺序,因此验证的时候需要检查访问数据顺序可能得不一致:

  • RS(T)和WS(U) 是否有交集,对任何事务U,FIN(U) > START(T),如果有交集,则T的读可能与U的写乱序;

  • WS(T)和WS({U) 是否有交集,对任何事务U, Fin(U) > VAL(T),如果有交集,则T的写可能与U的写乱序。

Multiversion(mvcC)

对应上述每种乐观程度,都可以有多版本的实现方式,多版本的优势在于,可以让读写事务与只读事务互不干扰,因而获得更好的并行度,也正是由于这一点成为几乎所有主流数据库的选择。为了实现多版本的并发控制,需要给每个事务在开始时分配一个唯一标识TID,并对数据库对象增加以下信息:

  • txd-id,创建该版本的事务TID

  • begin-ts及end-ts分别记录该版本创建和过期时的事务TID

  • pointer: 指向该对象其他版本的链表

怎么浅析数据库并发控制

其基本的实现思路是,每次对数据库对象的写操作都生成一个新的版本,用自己的TID标记新版本begin-ts及上一个版本的end-ts,并将自己加入链表。读操作对比自己的TID与数据版本的begin-ts,end-ts,找到其可见最新的版本进行访问。根据乐观程度多版本的机制也分为三类:

1. Two-phase Locking (MV2PL)

与单版本的2PL方式类似,同样需要Lock Table跟踪当前的加锁及等待信息,另外给数据库对象增加了多版本需要的begin-ts和end-ts信息。写操作需要对最新的版本加写锁,并生成新的数据版本。读操作对找到的最新的可见版本加读锁访问。

2. Timestamp Ordering (MVTO)

对比单版本的Timestamp方式对每个数据库对象记录的Read TimeStamp(RT),Write TimeStamp(WT),Commited flag(C)信息外增加了标识版本的begin-ts和end-ts,同样在事务开始前获得唯一递增的Start TimeStamp(TS),写事务需要对比自己的TS和可见最新版本的RT来验证顺序,写入是创建新版本,并用自己的TS标记新版本的WT,不同于单版本,这个WT信息永不改变。读请求读取自己可见的最新版本,并在访问后修改对应版本的RT,同样通过判断C flag信息避免Read Uncommitted。

3. Optimistic Concurrency Control (MVOCC)

对比单版本的Validataion(OCC)方式,同样分为三个阶段,Read阶段根据begin-ts,end-ts找到可见最新版本,不同的是在多版本下Read阶段的写操作不在私有空间完成,而是直接生成新的版本,并在其之上进行操作,由于其commit前begin-ts为INF,所以不被其他事务课件;Validation阶段分配新的Commit TID,并以之判断是否可以提交;通过Validation的事务进入Write阶段将begin-ts修改为Commit TID。

相对于悲观的锁实现,乐观的机制可以在冲突发生较少的情况下获得更好的并发效果,然而一旦冲突,需要事务回滚带来的开销要远大于悲观实现的阻塞,因此他们各自适应于不同的场景。而多版本由于避免读写事务与只读事务的互相阻塞, 在大多数数据库场景下都可以取得很好的并发效果,因此被大多数主流数据库采用。可以看出无论是乐观悲观的选择,多版本的实现,读写锁,两阶段锁等各种并发控制的机制,归根接地都是在确定的隔离级别上尽可能的提高系统吞吐,可以说隔离级别选择决定上限,而并发控制实现决定下限。

从乐观悲观的程度以及单版本多版本选择上对可用的并发控制机制选择进行了划分,并介绍了各种机制大体的设计思路,而距离真正的实现还有比较大的距离,包括实现细节和配套机制。比如常用的各种类型的MVCC中,由于多版本的存在而带来的一些列如垃圾回收、索引管理、版本存储等相关问题。我们之后将以MyRocks为例看看并发控制在工程上的具体实现。

看完上述内容,你们掌握怎么浅析数据库并发控制的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网数据库频道,感谢各位的阅读!

您可能感兴趣的文档:

--结束END--

本文标题: 怎么浅析数据库并发控制

本文链接: https://www.lsjlt.com/news/69253.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么浅析数据库并发控制
    怎么浅析数据库并发控制,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。数据库事务隔离发展标准一文中,从标准制定的角度介绍了数据库的隔离级别,介绍...
    99+
    2024-04-02
  • 数据库并发控制的作用及示例分析
    数据库并发控制的作用及示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1.数据库并发控制的作用1.1 事务的概念在介绍并发控制前,首先需...
    99+
    2024-04-02
  • Lakehouse数据湖并发控制陷阱分析
    目录1. 概述2. 数据湖并发控制中的陷阱3. 模型 1:单写入,内联表服务4. 模型2:单写入,异步表服务5. 模型3:多写入1. 概述 如今数据湖上的事务被认为是 Lakehou...
    99+
    2024-04-02
  • Java中常见的并发控制手段浅析
    目录前言1.1 同步代码块1.2 CAS自旋方式1.3 锁1.4 阻塞队列1.5 信号量Semaphore1.6 计数器CountDownLatch1.7 栅栏 CyclicBarr...
    99+
    2024-04-02
  • golang怎么控制并发数
    在Go中,可以使用goroutine和channel来控制并发数。 首先,可以使用make函数创建一个带有指定并发数的channel...
    99+
    2023-10-21
    golang
  • golang怎么控制并发数量
    在Go语言中,可以使用goroutine和channel来控制并发数量。 首先,可以使用goroutine来并发执行任务。例如,有一...
    99+
    2023-10-26
    golang
  • GO并发控制库Concurrency怎么使用
    这篇文章主要介绍“GO并发控制库Concurrency怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“GO并发控制库Concurrency怎么使用”文章能帮助大家解决问题。Concurrenc...
    99+
    2023-07-04
  • 掌控MySQL并发:深度解析锁机制与并发控制
    前一篇MySQL读取的记录和我想象的不一致——事物隔离级别和MVCC 讲了事务在并发执行时可能引发的一致性问题的各种现象。一般分为下面3种情况: 读 - 读情况:并发事务相继读取相同的记录。读取...
    99+
    2023-09-18
    MySQL并发控制 隐式锁 插入意向锁 行锁 表锁
  • golang控制并发数怎么实现
    在Go语言中,可以使用goroutine和channel来实现并发控制。下面是一种常见的实现方式: 创建一个有缓冲的channel...
    99+
    2023-10-21
    golang
  • JMeter 控制并发数
    文章目录 一、误区二、正确设置 JMeter 的并发数总结 没用过 JMeter 的同学,可以先过一遍他的简单使用例子 https://blog.csdn.net/weixin_42132143/article/detai...
    99+
    2023-08-18
    jmeter java 开发语言
  • golang的最大并发数怎么控制
    在Golang中,可以通过控制goroutine的数量来控制最大并发数。 一种常见的方法是使用带有缓冲的channel来限制并发数。...
    99+
    2023-10-21
    golang
  • 浅析php怎么操作数据库
    数据库是网络编程的重要组成部分,它用于存储和管理大量的数据。在网络应用中,对于用户信息、产品信息及其他数据信息都需要进行存储和管理,因此对于数据库的操作是开发网站必不可少的一部分。PHP作为一种广泛应用的后端服务器编程语言,也为我们提供了一...
    99+
    2023-05-14
    php 数据库
  • 高级 PHP 数据库连接:事务、锁和并发控制
    非常抱歉,由于您没有提供文章标题,我无法为您生成一篇高质量的文章。请您提供文章标题,我将尽快为您生成一篇优质的文章。...
    99+
    2024-05-21
  • 数据库中的并发控制:保持多用户和谐
    ...
    99+
    2024-04-02
  • redis怎么解决库存并发问题实现数量控制
    本篇内容介绍了“redis怎么解决库存并发问题实现数量控制”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!redis是单进程,阻塞式,在同一时...
    99+
    2023-06-29
  • python 协程并发数控制
    目录多线程之信号量协程中使用信号量控制并发aiohttp 中 TCPConnector 连接池前言: 本篇博客要采集的站点:【看历史,通天下-历史剧网】 目标数据是该站点下的热门历史...
    99+
    2024-04-02
  • MySQL中怎么实现并发控制
    今天就跟大家聊聊有关MySQL中怎么实现并发控制,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。锁锁分为读锁和写锁两种,也称作共享锁和排他锁。因为多个...
    99+
    2024-04-02
  • Linux中Shell多进程并发以及并发数控制的示例分析
    这篇文章主要介绍了Linux中Shell多进程并发以及并发数控制的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1. 基础知识准备1. linux后台进程Unix是一...
    99+
    2023-06-10
  • JavaScript中怎么实现并发控制
    这篇文章给大家分享的是有关JavaScript中怎么实现并发控制的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 在日常开发过程中,你可能会遇到并发控制...
    99+
    2024-04-02
  • PHP开发缓存的数据一致性与并发控制
    PHP开发缓存的数据一致性与并发控制,需要具体代码示例概述:在PHP开发中,缓存是一种常见的技术手段,用于提高数据读取速度和减轻数据库压力。然而,缓存带来了数据一致性和并发控制的挑战,因为在多线程环境中,不同的读写操作可能同时发生。本文将介...
    99+
    2023-11-07
    缓存 PHP开发 数据一致性 关键词:
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作