【数据库技术】2PL(两阶段锁)下的死锁与饥饿处理手段

2024-04-14 01:48

本文主要是介绍【数据库技术】2PL(两阶段锁)下的死锁与饥饿处理手段,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

事务处理-2PL下的死锁与饥饿

  • 2PL——2阶段锁存在的问题
  • 一、死锁与等待图
    • 1. 死锁(Deadlock)
    • 2. 等待图(Wait-for graph)
  • 二、死锁的处理手段
    • 1. 死锁预防
    • 2. 死锁检测
      • a. 撤销
      • b. 超时
  • 三、饥饿与饿死
  • 总结


2PL——2阶段锁存在的问题

在这里插入图片描述
两阶段锁协议通常包括扩张和收缩两个阶段。在扩张阶段,事务将获取锁,但不能释放任何锁。在收缩阶段,可以释放现有的锁,但不能获取新的锁。上图是一个典型的遵循2PL协议的序列表。看似严格保证了序列化,但实际存在着死锁的风险。
例如:当T1’在扩张阶段,获取了Y的读锁,并读取了Y,此时想要去获取X的写锁,却发现T2’的读锁锁定了X,而T2’也想要获取Y的写锁。简而言之,T1’不得到X是不会释放Y的,T2’不得到Y也是不会释放X的,这便陷入了循环,便形成了死锁。
本文就这一问题展开对死锁的两种处理方法的介绍,希望能用更通俗的语言让大家理解


一、死锁与等待图

1. 死锁(Deadlock)

死锁是指集合中的每个事务都在等待队列中,等待其他事务释放某个项上的锁。但是因为另一个事务也在等待,所以它永远不会释放锁。简而言之就是,我在等你主动,你也在等我主动,最后的结果是我俩都陷入僵局,什么都做不了。

通常检验一个事务执行序列是否发生死锁,可以用等待图(wait-for graph)来形象地描述。还是拿上面的例子来说。
等待图
图(a)就是我在上文中描述死锁的产生过程。图(b)就是等待图,从图中我们可以形象地看到,T1’在向T2’索取X,T2’在向T1索取Y,这便在图中形成了环,便发生了死锁。
死锁一旦发生,进程或事务将面临饥饿(Starvation),甚至最终饿死

2. 等待图(Wait-for graph)

等待图是一种分析死锁的有效工具。它是有向图,其中节点表示事务,带有箭头的有向边表示“等待”关系,箭头的方向就是等待的方向。例如,上图(b)中,T1’在等待T2’的X,T2’在等待T1’的Y。
定理:当且仅当等待图中至少存在一个环,则存在一个死锁。

示例:针对下图给出的序列,若用r表示读,w表示写,S表示读锁,X表示写锁,US表示释放读锁,UX表示释放写锁。
S1(X) r1(X); S2(Z) r2(Z); S3(X) r3(X); S1(Z) US1(X) r1(Z); S2(Y) US2(Z) r2(Y); X2(Z) US2(Y) w2(Z); X1(X) US1(Z) w1(X); X3(Y) US3(X) w3(Y); X2(Y) UX2(Z) w2(Y); UX2(Y)
在这里插入图片描述

转化为等待图为:
在这里插入图片描述
这样便形成了一个闭环,故发生了死锁。

二、死锁的处理手段

1. 死锁预防

如何来预防死锁的发生?
有人说:那我可以保守一点,直接让每个事务在执行前直接先把需要读写的项目,全部锁定。如果无法全部锁定,那我就一直等待,直到可以全部锁定我才开始这项事务。
显然,这个方案严重降低了并发性,并不是一个优秀的方案。
又有人说:那我可以对这些待读写的项目提前排个序啊,确保事务在执行过程中可以顺利锁定它们不就好了。这显然是不切实际的,这要求系统或程序提前知道待读写的项目的操作顺序。同样的这也大幅降低了并发性

为了保证并发性,我们考虑在发现即将有死锁的苗头时,主动让事务中止回滚或阻塞等待。下面介绍一种基于时间戳的死锁预防协议。它分为剥夺式和非剥夺式的。
首先引入事务时间戳这一概念,用TS(Ti)表示,数值越小代表开始越早,也表示该事务越“老”。例如上面的例子中,最早开始的事务是T1’,其次是T2’,第三是T3’,则TS(T1’) = 1,TS(T2’) = 2, TS(T3’) = 3,一旦开始这三个时间戳就为定值,不再随事务执行而改变。
对于这一协议,假设事务Ti试图锁定X,但无法上锁,因为此时X被其它事务Tj锁定。

  • Wait-die 等待-死亡策略:该策略是非剥夺式的。如果Ti的时间戳TS(Ti) < TS(Tj), 那么称Ti更老,则Ti可以继续等待。否则Ti直接中止并回滚,并之后重新以之前相同的时间戳启动。该策略可以这么理解:我们到达同一个工具间工作,我是一个性情温和的人,我先到但我后需要,既然现在你正在使用,那我愿意在这等你用完我再用。但如果我后到,我看到你正在用,那我直接选择回家,不浪费时间,下次再来。
  • Wound-wait 伤害-等待策略:该策略是剥夺式的。如果Ti的时间戳TS(Ti) < TS(Tj), 那么称Ti更老,则直接中止Tj并回滚,Ti抢占其资源,之后以同样的时间戳重新启动Tj。否则Ti继续等待。该策略可以这么理解:我是一个脾气暴躁的人,永远只认先到先得这个道理。如果现在我需要使用,那你必须让给我,你下次再来吧。但要是我后到呢,那我也不甘心,我就在原地等你用完我就用。

让我们来看看在这两种策略下,上面的例子中出现的死锁将如何被预防吧:
在这里插入图片描述

2. 死锁检测

处理死锁的另一种方法是死锁检测,系统检查是否存在死锁状态。如果我们知道事务之间的干扰很小,也就是说,如果不同的事务很少同时访问相同的项目,那么这个解决方案就很有吸引力。如果事务很短且每个事务只锁定少数项目,或者事务负载很轻,就会发生这种情况。另一方面,如果事务很长并且每个事务使用许多项,或者如果事务负载很重,那么使用死锁预防方案可能会比较有利。

一种简单的检测思路便是让系统构建并维护一张等待图,当存在等待时,构建等待边【详见上文对等待图的介绍】,当等待结束,成功获取到锁时,删除这条边。当且仅当检测到图中存在至少一个环时,就检测到死锁状态。
该方法的关键是要确定系统什么时候去维护这张等待图。是定时维护?还是定事务执行的次数维护?周期太短,维护过频将导致过多的开销,降低性能。但周期太长又不能及时检测到死锁

检测到死锁之后,如何去处理死锁(解除死锁)呢?

通常有两种手段:撤销或超时

a. 撤销

通常我们选择在检测到死锁发生的时候,优先去撤销当前已经执行过的更新次数最少的事务。保留那些已经运行了较长时间的事务。这里如何去制定一个更合理、更公平的撤销策略,诞生了一系列算法,它们被统称为受害者选择算法(victim selection)

b. 超时

另一个处理死锁的简单方案是使用超时。该方法具有开销小、简单等优点,是一种实用的方法。在此方法中,如果事务等待的时间超过系统定义的超时时间,则系统假定事务可能死锁并中止它——不管死锁是否实际存在。

三、饥饿与饿死

当我们使用锁时,可能发生的另一个问题是饥饿,当系统中的其他事务正常地继续时,一个事务在一段较长时间内,一直处于等待阶段,始终不能获取到资源时,就会发生饥饿

如果锁定项的等待方案不公平,即某些事务的优先级高于其他事务,则可能发生这种情况。如果长时间得不到资源,即使最后得到了资源,执行完毕后已经达不到预期的结果,便被称为饿死。饿死这一现象在CPU进行进程调度时更为常见。

解决饥饿问题的方法

  • 建立一个公平的等待机制。比如使用先到先服务的队列;事务可以按照它们最初请求锁的顺序锁定项目。
  • 等待越久优先级越高。允许某些事务优先于其他事务,但等待的时间越长,事务的优先级就越高,直到它最终获得最高优先级并继续执行。如果算法重复选择与受害者相同的事务,也会因为受害者选择而发生饥饿,从而导致它中止并永远无法完成执行。该算法可以对多次中止的事务使用更高的优先级,以避免这个问题。前面我们讨论过的的等待-死亡和伤害-等待方案都避免了饥饿,因为它们重新启动一个事务时,保留其原始时间戳,因此同一个事务重复中止的可能性很小。

总结

以上就是今天要讲的内容,本文仅仅简单介绍了2阶段锁下存在的死锁问题,简要解释了死锁与等待图,死锁的处理手段和饥饿与饿死的概念。希望这篇文章对理解死锁能有实质性帮助。

转载请注明出处。
参考资料:

操作系统——死锁的概念以及死锁处理策略
《Fundamentals of Database Systems 7th edition》 Ramez Elmasri and Shamkant B. Navathe
全局死锁与等待图-百度文库

这篇关于【数据库技术】2PL(两阶段锁)下的死锁与饥饿处理手段的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/901784

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是