如何使用封锁来实现并发控制

  • 前言
  • 数据库并发控制
    • 第一类丢失更新(回滚丢失 lost update)
    • 第二类丢失更新(两次更新 second lost update)
  • 封锁
    • 封锁协议
      • 一级封锁协议
      • 二级封锁协议
      • 三级封锁协议
      • 两阶段封锁协议
  • 封锁产生的问题-死锁

前言

 随着数据库应用的不断发展,数据规模逐渐升级,为了提高效率。往往会将多个事务并发的执行。而多个事务并发可能会同时存取同一数据,产生数据不一致的情况。比如“脏”读,不可重复读等。所以数据库管理系统(简称DBMS),必须提供并发控制机制。使得并发的事务在冲突时串行化执行。这种调度称为可串行化调度。
  并发控制主要有两种方式,封锁和时间戳。我们先来讨论用封锁的方式来保证事务并发控制中的一致性问题。封锁方式是基于各种锁来进行并发控制。在封锁机制中,当多个事务同时访问同一数据时,应对其进行封锁请求的授予或等待。而加锁可能带来死锁问题,所以加锁是要进行死锁检测,一旦被发现死锁则回滚代价最小的事务。

数据库并发控制

 数据库管理系统(DBMS)中的并发控制是为了确保在多个事务同时存取数据库中的同一数据时,不破坏事务的一致性和隔离性。不进行并发控制可能会造成以下问题。

第一类丢失更新(回滚丢失 lost update)

 当两个事务更新相同的元素,如果一个事务被提交,而另一个事务却被回滚,那么会连通先提交的事务所做的更新也被回滚。如图所示:

时间 取款事务 转账事务
T1 开始事务
T2 开始事务
T3 查询余额1000元
T4 查询余额1000元
T5 取出100元,余额为900元
T6 提交事务
T7 汇出100元,余额为900元
T8 回滚事务
T9 丢失更新(银行损失100元) 余额恢复为1000元

第二类丢失更新(两次更新 second lost update)

 无法重复读取的特例。有两个并发事务同时读取同一行数据,其中一个会对它进行修改提交,而另一个也进行修改提交。这也会造成第一次写操作失败。如图所示:

时间 取款事务 转账事务
T1 开始事务
T2 开始事务
T3 查询余额为1000元
T4 查询余额为1000元
T5 取出100元,余额为900元
T6 提交事务
T7 转入100元,余额为1100元
T8 丢失更新,银行损失100元

封锁

 所谓封锁就是事务T在对某个数据对象(表、记录等)操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制。基本的封锁类型有两种:排他锁(Exclusive Locks,简称X锁)和共享锁(Share Locks,简称S锁)。排它锁又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。共享锁又称读锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能在对A加S锁,而不能加X锁,直到T释放A上的S锁。
 排它锁与共享锁的控制方式可以用如下图的相容矩阵表示,相容性矩阵中对应的每种封锁方式有一行和一列。行对应于数据库元素A上某一事务已经持有的锁,列对应于A上申请的锁。

S X
S Y N
X N N

Y=Yes,表示申请的锁请求与已持有的锁是相容的请求
N=No,表示申请的锁请求与已持有的锁是不相容的请求

封锁协议

 在运用X锁和S锁对对象加锁时,还需要约定一些规则,例如何时申请X锁或S锁、持锁时间、何时释放等。称这些规则为封锁协议(Locking Protocol)。对封锁方式规定不同的规则,就形成了各种不同的封锁协议。封锁协议的规则是对隔离级别的实现,在封锁协议中的丢失更新是指第二类丢失更新。

一级封锁协议

 事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。而这级封锁协议是不对读数据加锁的。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。
 一级封锁协议可以防止丢失更新,并保证事务T是可恢复的。使用一级封锁协议可以解决丢失更新问题,但它不能保证可重复读和不读“脏”数据。
 这种情况符合SQL99中对读未提交隔离级别的效果,可以认为该级锁协议对应的就是读未提交。

二级封锁协议

 一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,读完后立即释放S锁。
  二级封锁协议除防止了丢失更新,还可以进一步防止读“脏”数据。但在二级封锁协议中,由于读完数据后即可释放S锁,所以它不能保证可重复读。
这种情况符合SQL99中对读已提交隔离级别的效果,可以认为该级锁协议对应的就是读已提交。

三级封锁协议

 一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。
 三级封锁协议除防止了丢失修改和不读“脏”数据外,还进一步防止了不可重复读,但并没有完全防止幻读,因为该级协议中并未对可能不存在的数据加锁,而并发事务中可能会插入新数据导致前面的事务产生幻读。
 这种情况符合SQL99中对可重复读隔离级别的效果,可以认为该级锁协议对应的就是可重复读。
 如果在共享排他锁的基础上再加入范围锁,则应用三级封锁协议也能防止幻读,即达到了SQL99中对可串行化隔离级别的效果。

两阶段封锁协议

 在对任何数据读、写操作之前,事务首先或得该数据的封锁,并且不能释放任何锁。在释放一个封锁之后,事务不再获得任何封锁。
例如:
 事务T1的封锁序列SlockA->SlockB->XlockC->UnlockC->UnlockB->UnlockA;
 事务T2的封锁序列Slock A ->Unlock A -> Slock B -> Xlock C ->Unlock C ->Unlock B。
 事务T1遵守两阶段锁协议,而事务T2不遵守两阶段锁协议。
 两阶段封锁协议保证了事务的串行化调度,但同时,一个事务的失败可能会引起一连串事务的回滚。为避免这种情况的发生,需要进一步加强对两阶段封锁协议的控制:

  1. 严格两阶段封锁协议:除了要求封锁是两阶段之外,还要求事务持有的所有排它锁必须在事务提交之后方可释放。这个要求保证未提交事务所写的任何数据,在该事务提交之前均以排它锁封锁,防止其他事务读取这些数据。
  2. 强两阶段封锁协议:除了要求封锁是两阶段之外,还要求事务提交之前不得释放任何锁(包括共享锁)。

封锁产生的问题-死锁

 以上所有的封锁协议都不足以保证不会发生死锁,因为死锁是两个或者多个事务都各自锁定一些数据库元素,然后又都请求对已被其他事务封锁的数据对象封锁,从而出现死等的情况。

 事务T1先访问数据库元素R1并且被授予了对R1的封锁,同时需要访问数据库元素R2;
 事务T2先访问数据库元素R2并且被授予了对R2的封锁,同时需要访问数据库元素R1。
 这时T1由于T2已经锁定R2,则等待T2释放R2才能继续,同样T2要等待T1释放R1才能继续,导致了死锁。

一文搞懂如何使用封锁来实现并发控制相关推荐

  1. 一文搞懂RNN(循环神经网络)

    基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...

  2. 一文搞懂 Python 的 import 机制

    一.前言 希望能够让读者一文搞懂 Python 的 import 机制 1.什么是 import 机制? 通常来讲,在一段 Python 代码中去执行引用另一个模块中的代码,就需要使用 Python ...

  3. python语言语句快的标记是什么_一文搞懂Python程序语句

    原标题:一文搞懂Python程序语句 程序流 Python 程序中常用的基本数据类型,包括: 内置的数值数据类型 Tuple 容器类型 String 容器类型 List 容器类型 自然的顺序是从页面或 ...

  4. 一文搞懂 Java 线程中断

    转载自   一文搞懂 Java 线程中断 在之前的一文<如何"优雅"地终止一个线程>中详细说明了 stop 终止线程的坏处及如何优雅地终止线程,那么还有别的可以终止线程 ...

  5. 一文搞懂HMM(隐马尔可夫模型)-Viterbi algorithm

    ***一文搞懂HMM(隐马尔可夫模型)*** 简单来说,熵是表示物质系统状态的一种度量,用它老表征系统的无序程度.熵越大,系统越无序,意味着系统结构和运动的不确定和无规则:反之,,熵越小,系统越有序, ...

  6. 一文搞懂如何使用Node.js进行TCP网络通信

    摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...

  7. 【UE·蓝图底层篇】一文搞懂NativeClass、GeneratedClass、BlueprintClass、ParentClass

    本文将对蓝图类UBlueprint的几个UClass成员变量NativeClass.GeneratedClass.BlueprintClass.ParentClass进行比较深入的讲解,看完之后对蓝图 ...

  8. 一文搞懂AWS EC2, IGW, RT, NAT, SG 基础篇下

    B站实操视频更新 跟着拉面学习AWS--EC2, IGW, RT, NAT, SG 简介 长文多图预警,看结论可以直接拖到"总结"部分 本文承接上一篇文章介绍以下 AWS 基础概念 ...

  9. 一文搞懂CAN FD总线协议帧格式

    目录 1.为什么会出现CAN FD? 2.什么是CAN FD? 3.CAN FD和CAN总线协议帧异同 4.解析CAN FD帧结构 4.1.帧起始 4.2.仲裁段 4.3.控制段 4.4.数据段 4. ...

  10. 一文搞懂 Traefik2.1 的使用

    原文链接:一文搞懂 Traefik2.1 的使用 一文搞懂 Traefik2.1 的使用 核心概念 安装 ACME 中间件 灰度发布 流量复制 TCP 简单 TCP 服务 带 TLS 证书的 TCP ...

最新文章

  1. C++实现类不可复制
  2. PPT 下载 | 神策数据朱德康:用户中台建设实践解析
  3. DICOM文件格式与编程(转)
  4. 信息学奥赛一本通 1090:含k个3的数 | OpenJudge NOI 1.5 30
  5. SpringBoot加载静态资源
  6. 人生理解---2、看《程序员年龄增大后的职业出路是什么》有感
  7. After Effect CC 2019插件
  8. win7系统opc服务器配置,win7 设置opc服务器
  9. 配置与管理Ubuntu 21.10
  10. 手把手教你爬取任意日期全部股票分时数据~
  11. 最少操作次数(英雄会)
  12. 还原SQL Server数据库
  13. 《黑匣子思维:我们如何更理性地犯错》iphone部分
  14. 苹果CMS安装详细教程
  15. (自用随笔)PAT A1010
  16. 【总结】搜索引擎の精确搜索法
  17. 在使用集合中的contains(),要根据实际情况改写集合中对象的equals(Object obj)方法------改写List集合中equals(Object obj)的方法
  18. word中选择单倍行距,但是有些段落的行距还是不一样
  19. mac上最好用的5款epub阅读器
  20. 基于SpringBoot的ERP系统,自带进销存+财务+生产功能

热门文章

  1. 关于自然语言理解的一些理解
  2. VS2013中添加现有窗体项
  3. android A problem occurred starting process
  4. uniapp仿网易云音乐项目(发布小程序、H5和安卓App)
  5. Ubuntu 22.04 双网卡网关设置报错:Conflicting default route declarations for IPv4
  6. 基于微信小程序的物流仓储系统
  7. H.265和VP9视频编码要被干掉?解读全新AV1编码标准
  8. 《Python数据分析与挖掘实战》第13章——回归+DNN
  9. 整理了 47 个 Python 人工智能库
  10. using runtime html4,为什么我不能在C#中引用System.Runtime.Serialization.Json