多粒度封锁-封锁粒度、多粒度封锁模式

一、引言

1、若采用封锁技术实现并发控制,事务在访问数据库对象前要在数据库对象上加锁,为提高事务的并发程度,商用DBMS会采用一种多粒度封锁方法

2、事务可访问的数据库对象可以是逻辑单元,包括关系、关系中的元组、关系的属性值或属性值集合、关系上的索引项或整个索引、甚至整个数据库等,也可以是物理单元,比如数据所占用的磁盘块 、索引所占用的磁盘块、磁盘块中的物理记录等

3、多粒度封锁技术根据封锁的数据对象的大小不同化分封锁的粒度,将锁加在不同粒度的数据库对象上。在具体DBMS应用时,实现不同的多粒度封锁模式

二、封锁粒度

1、封锁粒度:封锁单元的大小。如果封锁对象单元小,则称为细粒度,否则称为粗粒度

(1)实际应用中,通常细粒度锁是加在元组上的锁,称为元组锁,也称为行级锁

(2)粗粒度锁是加在关系上的锁,称为关系锁,也称为表级锁

对关系加上粗粒度锁后,关系中的所有元组,也被隐式地加上了同样的锁,因此,相对粗粒度锁,使用细粒度锁的事务可以只封锁事务实际访问的数据对象,事务的并发程度会更好

2、比如,对于银行业务系统

如果将账户关系表作为封锁对象,整个关系只能被一个事务加锁,由于业务系统中会有并发的许多事务,对账户表中的不同用户的信息进行更新,这些事务都需要账户关系表上的一个排他锁,那么同一时间只能有一个存款或取款业务能进行,系统中事务的并发程度会很低

 

如果将关系表中的元组作为封锁对象,对不同账户信息进行操作的事务都可以同时对账户信息进行更新

虽然使用细粒度锁使事务的并发程度更好,但由于锁的信息要占用系统的内存空间,并需要DBMS的并发控制机制花费系统时间来管理

3、因此封锁粒度的选择需同时考虑管理锁的开销事务并发度两个因素,以获得最佳的系统性能

4、为此,有的DBMS实现了多粒度封锁功能,来更好地满足应用需求和提高系统性能

(1)比如,对于需要处理大量元组的事务,可以选择关系为封锁粒度

(2)而对于只处理少量元组的用户事务,选择以元组为封锁粒度更合适

(3)也可允许事务根据操作需要来选择封锁粒度

三、多粒度封锁模式

1、不同的DBMS实现的多粒度封锁模式不同,比如SQL Server提供了如下几种锁

(1)NOLOCK锁:用于SELECT语句,读数据前不用申请数据对象上的锁

(2)TABLOCK锁:在关系表上加共享锁,在读完数据后立即释放锁

(3)HOLDLOCK保持锁:用于TABLOCK后,可将共享锁保留到事务完成,而不是读完数据立即释放锁

(4)UPDLOCK锁:在操作语句中满足条件的指定元组上加更新锁,允许对这些元组进行更新操作,其他事务可以对同一关系表中的其他元组也加更新锁,但不允许对表加共享锁和共享锁

(5)TABLOCKX锁:在关系表上加排他锁

2、该封锁模式对应的封锁策略,可用这个锁相容矩阵来描述

3、SQL Server提供在SELECT、INSERT、UPDATE和DELETE等语句中添加WITH子句来显示地进行封锁操作

SELECT SNO,GRADE
FROM SC WITH(TABLOCK)
WHERE SNO='202218014030'

4、下面我们基于创建的学生选课数据库,在SQL Server上通过两个并发事务的执行,来理解多粒度封锁技术的应用。

(1)我们通过在SQL Server的对象资源管理器上打开两个查询窗口来执行两个并发事务,请在事务的并发执行过程中并发调度中每一步的操作结果,分析操作的封锁情况以及多粒度封锁对事务的并发性和数据一致性的影响

(2)在查询窗口1开始执行事务T1,首先对关系表SC表中SNO='202218014030' 的元组进行查询,使用TABLOCK锁得到满足条件的两个元组

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';

(3)再在查询窗口2开始执行事务T2,修改学号为'202218014030'的学生的成绩为99,使用UPDLOCK锁

BEGIN TRAN T2UPDATE SC WITH(UPDLOCK)SET GRADE=99WHERE SNO='202218014030';

语句可以执行,说明事务T1读完数据后立刻释放了封锁

(4)返回事务T1继续运行事务,使用NOLOCK锁SC中SNO='202218014030'的元组,查询可执行,事务T1可读到事务T2修改后的数据,看到SC表中SNO='202218014030'的元组的GRADE值被更新,而事务T2没有提交,事务T1读取了脏数据

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(NOLOCK)WHERE SNO='202218014030';

 (5)事务T1继续执行,使用UPDLOCK锁,修改学号为‘202218014032’的学生的成绩为96,语句可以执行,说明事务T2只在SNO='202218014030'的元组上加上了更新锁

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(NOLOCK)WHERE SNO='202218014030';UPDATE SC WITH(UPDLOCK)SET GRADE=96WHERE SNO='202218014032';

(6)返回事务T2继续运行事务,使用TABLOCK锁,对SC表中SNO='202218014032'的元组进行查询,无结果显示,事务T2处于锁等待状态

BEGIN TRAN T2UPDATE SC WITH(UPDLOCK)SET GRADE=99WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014032';

(7)返回事务T1提交事务,再返回事务T2可看到事务T2已执行,读取了事务T1提交后的数据,事务T2不会读取脏数据

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(NOLOCK)WHERE SNO='202218014030';UPDATE SC WITH(UPDLOCK)SET GRADE=96WHERE SNO='202218014032';
COMMIT TRAN T1;

(8)然后回滚事务T2,对事务T2中修改的元组进行查询,可见对SC表中SNO='202218014030'的元组的修改被撤销了,而已提交的事务T1已读取了事务T2中间修改过的值,读取了脏数据

BEGIN TRAN T2UPDATE SC WITH(UPDLOCK)SET GRADE=99WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014032';
ROLLBACKSELECT *FROM SCWHERE SNO='202218014030';

5、通过前面两个并发事务的执行,可以看到

(1)SELECT语句加NOLOCK锁可以使并发操作立即执行,但会读取脏数据

(2)TABLOCK锁是一个短期读锁,可以避免读脏数据

(3)UPDLOCK锁是一个长期写锁 ,是细粒度锁,元组锁

6、下面来看另一组并发事务的执行

(1)在查询窗口1开始执行事务T1,还是首先使用TABLOCK锁,对关系表SC表中SNO='202218014030'的元组进行查询,仍然得到满足条件的3个元组

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';

 

(2)在查询窗口2执行更新语句,也就是一个隐式定义的事务,使用UPDLOCK锁修改修改学号为‘202218014030’的学生的成绩为99,语句可以执行,说明事务T1在读完数据后立刻释放了封锁

UPDATE SC WITH(UPDLOCK)SET GRADE=99WHERE SNO='202218014030';

 (3)返回事务T1继续运行事务,再次执行相同的查询操作,操作可执行,得到的查询结果与前一次查询结果不一样,说明短期读锁不具有可重复读特性

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';

(4)若在事务T1将TABLOCK后加保持锁,再进行查询

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK HOLDLOCK)WHERE SNO='202218014030';

 

(5)然后再在查询窗口2执行更新语句, 此时操作不再执行

UPDATE SC WITH(UPDLOCK)SET GRADE=99WHERE SNO='202218014030';UPDATE SC WITH(UPDLOCK)SET GRADE=0WHERE SNO='202218014030';

(6)返回查询窗口1,在事务T1中再次执行前面的查询操作,查询结果不变,说明长期读锁具有可重复读特性

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK HOLDLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK HOLDLOCK)WHERE SNO='202218014030';

(7)待事务T1提交后,查询窗口2中的操作才可执行

BEGIN TRAN T1SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK HOLDLOCK)WHERE SNO='202218014030';SELECT SNO,GRADEFROM SC WITH(TABLOCK HOLDLOCK)WHERE SNO='202218014030';
COMMIT TRAN T1

 

7、通过前面两个并发事务的执行可以看到

(1)使用TABLOCK锁,事务可以避免读脏数据,但数据不具有可重复读的特性 

(2)使用HOLDLOCK锁,可使TABLOCK锁变为长期读锁,可以保证数据的可重复读特性

8、多粒度封锁的实现

(1)DBMS为实现多粒度封锁,在事务对数据对象进行显示封锁的时候,并发控制机制为了更好地解决元组锁和关系锁之间的冲突,在给元组加锁前,要给元组所在的关系加一个意向锁

(2)意向锁的作用就是标识关系中某些元组正在被锁定其他用户将要锁定关系中的某些元组

(3)意向锁是由系统隐式进行添加的,不能人为干预

(4)根据事务要对数据对象要进行的读写操作不同,意向锁也有意向共享锁(IS)意向排他锁(IX)之分

(5)意向锁之间不会产生冲突互相兼容,与共享锁和排他锁间的兼容性,可见给出的锁相容矩阵

四、小结

1、运用多粒度封锁技术提高并发事务的并发程度

2、用户利用DBMS提供的多粒度封锁模式,根据应用需求,选择封锁粒度和封锁类型,通过显示地为事务中的操作加锁,可控制事务的并发执行

3、但在事务的并发执行过程中,多粒度封锁的灵活应用,在提高事务的并发程度的同时,也会带来数据的不一致问题用户需要根据事务对并发性和数据一致性的要求合理地使用锁

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】map和set详解

目录 1. 关联式容器 2. 键值对pair 3. 树形结构的关联式容器 4. set 4.1 set的介绍 4.2 set的构造 4.3 set的迭代器 4.4 set的容量 4.5 set的常用函数 5. multiset 6. map 6.1 map的介绍 6.2 map的构造 6.3 map的迭代器 6.4 map的容量 6.5 map的operator[] 6.6…

Python入门 2024/7/6

目录 元组的定义和操作 字符串的定义和操作 字符串 字符串的替换 字符串的分割 字符串的规整操作(去除前后空格) 字符串的规整操作(去掉前后指定字符串) 操作 字符串的替换 字符串的分割 字符串的规整操作 统计字符串的…

ESP32——物联网小项目汇总

商品级ESP32智能手表 [文章链接] 用ESP32,做了个siri?!开源了! [文章链接]

JSP WEB开发(一) JSP语言基础

目录 JSP JSP简介: JSP页面 JSP运行原理 JSP脚本元素 JAVA程序片 局部变量 全局变量和方法的声明 全局变量 方法的声明 程序片执行特点 synchronized关键字 表达式 JSP指令标记 page指令 include指令 JSP动作标记 JSP动作元素include和include指令的…

测试环境:使用OpenSSL生成证书并配置Https

文章目录 需求1、安装OpenSSL1.1、安装包下载1.2、安装(以window 64位为例)1.3、配置环境变量(非必须) 2、生成证书2.1、新建文件夹2.2、生成根证书2.2.1、生成私钥2.2.2、生成根证书,并且自签名 2.3、服务端证书生成2…

前端根据目录生成模块化路由routes

根据约定大于配置的逻辑,如果目录结构约定俗成,前端是可以根据目录结构动态生成路由所需要的 route 结构的,这个过程是要在编译时 进行,生成需要的代码,保证运行时的代码正确即可 主流的打包工具都有对应的方法读取文…

设计模式之状态机模式

一、状态机模式介绍 状态机模式(State Machine Pattern)是一种用于描述对象行为的软件设计模式,属于行为型设计模式。在状态机模式中,对象的行为取决于其内部状态,并且在不同的状态下,对象可能会有不同的行…

Java信号量semaphore的原理与使用方法

Semaphore的基本概念 在Java中,Semaphore是位于java.util.concurrent包下的一个类。它的核心就是维护了一个许可集。简单来说,就是有一定数量的许可,线程需要先获取到许可,才能执行,执行完毕后再释放许可。 那么&…

Unity 简单载具路线 Waypoint 导航

前言 在游戏开发和导航系统中,"waypoint" 是指路径中的一个特定位置或点。它通常用于定义一个物体或角色在场景中移动的目标位置或路径的一部分。通过一系列的 waypoints,可以指定复杂的移动路径和行为。以下是一些 waypoint 的具体用途&…

YoloV8改进策略:Block改进|轻量实时的重参数结构|最新改进|即插即用(全网首发)

摘要 本文使用重参数的Block替换YoloV8中的Bottleneck,GFLOPs从165降到了116,降低了三分之一;同时,map50-95从0.937涨到了0.947。 改进方法简单,只做简单的替换就行,即插即用,非常推荐&#xf…

【leetcode52-55图论、56-63回溯】

图论 回溯【56-63】 46.全排列 class Solution:def permute(self, nums):result []self.backtracking(nums, [], [False] * len(nums), result)return resultdef backtracking(self, nums, path, used, result):if len(path) len(nums):result.append(path[:])returnfor i …

pdf怎么转换成图片格式文件,pdf文档怎么转换成图片格式

在数字化时代,pdf文件转换成图片格式是一种常见的操作,无论是在工作还是日常生活中,我们总会遇到需要将pdf文件转换为图片的需求。这可能是因为图片格式更易于分享、展示或编辑。那么,如何高效地将pdf转换成图片呢?本文…

QListWidget 缩略图IconMode示例

1、实现的效果如下&#xff1a; 2、实现代码 &#xff08;1&#xff09;头文件 #pragma once #include <QtWidgets/QMainWindow> #include "ui_QListViewDemo.h" enum ListDataType { ldtNone -1, ldtOne 0, ldtTwo 1, }; struct ListData…

Error in onLoad hook: “SyntaxError: Unexpected token u in JSON at position 0“

1.接收页面报错 Error in onLoad hook: "SyntaxError: Unexpected token u in JSON at position 0" Unexpected token u in JSON at position 0 at JSON.parse (<anonymous>) 2.发送页面 &#xff0c;JSON.stringify(item) &#xff0c;将对象转换为 JSO…

计算机网络——数据链路层(点对点协议PPP)

点对点协议PPP的概述 对于点对点的链路&#xff0c;目前使用得最广泛的数据链路层协议是点对点协议 PPP (Point-to-Point Protocol)。 它主要应用于两个场景&#xff1a; 用户计算机与ISP之间的链路层协议就是点对点协议 PPP&#xff0c;1999年公布了回以在以太网上运行的PPP协…

事务(数据库)

是一组操作的集合&#xff0c;是一个不可分割的工作单位&#xff0c;事物会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;这些操作要么同时成功&#xff0c;要么同时失败 create table account(id int auto_increment primary key comment 主键ID,name va…

人工智能在病理切片虚拟染色及染色标准化领域的系统进展分析|文献速递·24-07-07

小罗碎碎念 本期文献主题&#xff1a;人工智能在病理切片虚拟染色及染色标准化领域的系统进展分析 这一期文献的速递&#xff0c;是有史以来数量最大的一次&#xff0c;足足有十一篇&#xff0c;本来打算分两期写&#xff0c;但是为了知识的系统性&#xff0c;我决定咬咬牙&…

昇思MindSpore学习笔记5-01生成式--LSTM+CRF序列标注

摘要&#xff1a; 记录昇思MindSpore AI框架使用LSTMCRF模型分词标注的步骤和方法。包括环境准备、score计算、Normalizer计算、Viterbi算法、CRF组合,以及改进的双向LSTMCRF模型。 一、概念 1.序列标注 标注标签输入序列中的每个Token 用于抽取文本信息 分词(Word Segment…

常见的Java运行时异常

常见的Java运行时异常 1、ArithmeticException&#xff08;算术异常&#xff09;2、ClassCastException &#xff08;类转换异常&#xff09;3、IllegalArgumentException &#xff08;非法参数异常&#xff09;4、IndexOutOfBoundsException &#xff08;下标越界异常&#xf…

dell Vostro 3690安装win11 23h2 方法

下载rufus-4.5.exe刻U盘去除限制 https://www.dell.com/support/home/zh-cn/product-support/product/vostro-3690-desktop/drivers dell官网下载驱动解压到U盘 https://dl.dell.com/FOLDER09572293M/2/Intel-Rapid-Storage-Technology-Driver_88DM9_WIN64_18.7.6.1010_A00_01…