广告
返回顶部
首页 > 资讯 > 数据库 >【SQL SERVER】锁机制
  • 918
分享到

【SQL SERVER】锁机制

【SQLSERVER】锁机制 2018-04-02 17:04:21 918人浏览 无得
摘要

SQL Server中锁机制保证并发情况下的数据访问,开发过程中利用好索引减少数据,能减少数据扫描数据加锁的过程,合理规范使用事务,能减少死锁发生 锁定是 sql Server 数据库引擎用来同步多

【SQL SERVER】锁机制

SQL Server机制保证并发情况下的数据访问,开发过程中利用好索引减少数据,能减少数据扫描数据加锁的过程,合理规范使用事务,能减少死锁发生

锁定是 sql Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制。

  1. 基本概念
  2. 利用SQL Server Profiler观察锁
  3. 死锁产生的原因及避免
  4. 总结

基本概念

数据库引擎隔离级别

隔离级别定义
未提交的读取 隔离事务的最低级别,只能保证不读取物理上损坏的数据。 在此级别上,允许脏读,因此一个事务可能看见其他事务所做的尚未提交的更改
已提交的读取 允许事务读取另一个事务以前读取(未修改)的数据,而不必等待第一个事务完成。 SQL Server 数据库引擎保留写锁(在所选数据上获取)直到事务结束,但是一执行 SELECT 操作就释放读锁。 这是SQL Server 数据库引擎默认级别
可重复的读取 SQL Server 数据库引擎保留在所选数据上获取的读锁和写锁,直到事务结束。 但是,因为不管理范围锁,可能发生虚拟读取
可序列化 隔离事务的最高级别,事务之间完全隔离。 SQL Server 数据库引擎保留在所选数据上获取的读锁和写锁,在事务结束时释放它们。 SELECT 操作使用分范围的 WHERE 子句时获取范围锁,主要为了避免虚拟读取
 

锁粒度

资源说明
RID 用于锁定堆中的单个行的行标识符,也就是常说的行锁
KEY 索引中用于保护可序列化事务中的键范围的行锁
PAGE 数据库中的 8 KB 页,例如数据页或索引页,也就常说的业级锁
EXTENT 一组连续的八页,例如数据页或索引页
HoBT 堆或 B 树。 用于保护没有聚集索引的表中的 B 树(索引)或堆数据页的锁
TABLE 包括所有数据和索引的整个表
FILE 数据库文件
APPLICATioN 应用程序专用的资源
METADATA 元数据锁
ALLOCATION_UNIT 分配单元
DATABASE 整个数据库
 

锁类型

说明
共享 (S) 用于不更改或不更新数据的读取操作,如 SELECT 语句
更新 (U) 用于可更新的资源中。 防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁
排他 (X) 用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。 确保不会同时对同一资源进行多重更新
意向 (I) 用于建立锁的层次结构。 意向锁包含三种类型:意向共享 (IS)、意向排他 (IX) 和意向排他共享 (SIX)
架构 (Sch-) 在执行依赖于表架构的操作时使用。 架构锁包含两种类型:架构修改 (Sch-M) 和架构稳定性 (Sch-S)
大容量更新 (BU) 在将数据大容量复制到表中且指定了 TABLOCK 提示时使用
键范围 (Range) 当使用可序列化事务隔离级别时保护查询读取的行的范围。 确保再次运行查询时其他事务无法插入符合可序列化事务的查询的行
 

利用SQL Server Profiler观察锁

1. 准备数据10条数据

create table DataTable(Id int identity(1,1), [Name] varchar(50), [Address] varchar(200), CreateTime datetime2)
    
insert into DataTable
select "Wilson","广东省广州市",GETDATE() uNIOn all
select "Alice","北京市朝阳区",GETDATE() union all
select "Miksovsky","吉林省松原市",GETDATE() union all
select "Hines","甘肃省兰州市",GETDATE() union all
select "Kane","辽宁省沈阳市",GETDATE() union all
select "Gode","湖北省荆州市",GETDATE() union all
select "Chen","湖南省岳阳市",GETDATE() union all
select "Trenary","福建省厦门市",GETDATE() union all
select "Achong","广西省玉林市",GETDATE() union all
select "Nixon","江西省景德镇",GETDATE() 
View Code

2. 打开SQL Server Profiler选中锁事件,勾选type和mode,建议取消不需要观察的列,然后用列筛选器过滤要观察的DB

3. 查询数据

 可以看到在页面级别加上意向共享锁,因为我们数据只有一页

4. 更新一条数据

表上加上意向排它锁(IX),可以用select OBJECT_NAME(581577110) 查看objectid代表的东西

页级别加上意向更新锁(IU),告诉SQL Server引擎这里有更新锁

获取第一行的更新锁(U),这里条件匹配

页级别升级为意向排他锁(IX), 告诉SQL Server引擎这里有排他锁

第一个行更新锁 升级为排它锁(X)

释放锁

随条扫描后面的记录,只是条件不符合,也就不会升级锁级别

 

可以看到是全表扫描,因为没聚集索引(堆表),我们也没做一个主键,下面将Id添加主键然后再更新试试

alter table DataTable add constraint PK_DataTable primary key(Id asc)

 

 

 可以看出,直接在表,页级别加上意向排它锁(IX),然后在键上加上排它锁(X)

因为这里我们用主键更新,而且SQL Server主键默认是聚集索引,如果指定是非聚集索引主键,这里也会经历更新锁 到 排他锁,有兴趣的可以自行验证

5. 删除一条数据

 

 

 这次我们没用主键删除,过程和更新的第一种情况差不多,就不列了。

因为加了聚集索引,索引定位器执行聚集索引Key的hash,要验证是否那条记录,可以在删除前加上%%lockres%%去查

 

死锁产生的原因及避免

死锁产生的原因

微软文档是这样说

在两个或多个任务中,如果每个任务锁定了其他任务试图锁定的资源,此时会造成这些任务永久阻塞,从而出现死锁

我理解就是有2个事务循环依赖对方的资源导致产生死锁。

例如

事务A 获取 Row1 资源

事务B 获取 Row2 资源

事务A获取Row2资源,由于这时Row2是被事务B占有,所以必须等事务B完成

事务B获取Row1资源,由于这时Row1是被事务A占有,所以必须等事务A完成

SQL Server处理死锁策略

定期检查陷入死锁的任务

若检查到循环依赖

选择其中一个作为牺牲品,然后终止事务,然另外一个得以完成

模拟死锁

分别在两个不同的会话执行下面语句

begin tran;

update DataTable set Address = "上海市" where Id = 2;
--延迟5秒执行
WAITFOR DELAY "00:00:05";
update DataTable set Address = "上海市" where Id = 3;

commit;
begin tran;

update DataTable set Address = "上海市" where Id = 3;
--延迟5秒执行
WAITFOR DELAY "00:00:05";
update DataTable set Address = "上海市" where Id = 2;

commit;

执行一段时间,其中一个会出现下面错误

SQL Server Profiler 捕获死锁分析

打开Locks事件的死锁图形

 

 重新执行上面语句,模拟死锁,Profiler捕获到死锁

 

可以看出

进程56 请求的Key 的排它锁  被进程 54 占有

进程54 请求的Key 的排他锁 被进程 56 占有

形成了循环依赖

我们这里的Sql比较简单,而且没有用参数化执行,所以我们指定是哪一行被锁,线上的通常不能直接看到哪一行被锁

我们可以通过xml查看等待的资源,在xml里面有process-list 下面有多个process,process节点上面有个waitresource属性,这个指出每个进程等待的资源

锁类型:db_id : hobt_id : (hashvalue)

KEY: 6:72057594043760640 (61a06abd401c)

通过%%lockres%% 查到被锁资源

select %%lockres%%,* from DataTable where %%lockres%% = "(98ec012aa510)"

锁类型不一样,得到的会不一样,根据各自的格式用db_name / object_name  / dbcc去查到当前被锁的资源,有时候需要利用DBCC查询Page存储页面,可以参考上一篇文章【SQL SERVER】数据内部存储结构简单探索

避免死锁

首先需要说明死锁不能完全避免,但遵守特定的编码惯例可以将发生死锁的机会降至最低

 按同一顺序访问对象,一个获取锁,另外一个就必须等待

 避免事务中的用户交互 ,这样导致事务时间过长,容易造成死锁

 保持事务简短并处于一个批处理中,道理和2一样,尽量让事务运行时间短。

使用较低的隔离级别,这个看能不能接受脏读,幻读等副作用

总结

锁机制保证并发情况下的数据访问。

开发中应该尽量利用索引检索数据,特别是UPDATE/DELETE这种需要排它锁,应该利用唯一聚集索引字段更新(通常是主键)

规范使用事务能减少死锁发生

转发请标明出处:https://www.cnblogs.com/WilsonPan/p/12618849.html

参考文章

事务锁定和行版本控制指南 - SQL Server | Microsoft Docs

您可能感兴趣的文档:

--结束END--

本文标题: 【SQL SERVER】锁机制

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

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

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

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

下载Word文档
猜你喜欢
  • 【SQL SERVER】锁机制
    SQL Server中锁机制保证并发情况下的数据访问,开发过程中利用好索引减少数据,能减少数据扫描数据加锁的过程,合理规范使用事务,能减少死锁发生 锁定是 SQL Server 数据库引擎用来同步多...
    99+
    2018-04-02
    【SQL SERVER】锁机制
  • 深入理解 SQL Server 2008 的锁机制
    相比于 SQL Server 2005(比如快照隔离和改进的锁与死锁监视),SQL Server 2008 并没有在锁的行为和特性上做出任何重大改变。SQL Server 2008 引入的一个主要新特性是在...
    99+
    2022-10-18
  • SQL Server内存机制详解
    1.前言 对于数据库引擎来说,内存是一个性能提升的重要解决手段。把数据缓存起来,可以避免在查询或更新数据时花费多余的时间,而这时间通常是从磁盘获取数据时用来等待磁盘寻址的。把执行计划...
    99+
    2022-11-13
  • SQL Server中锁的用法
    目录通过锁可以防止的问题1、脏读2、非重复性读取3、幻读4、丢失更新可以锁定的资源锁升级和锁对性能的影响锁定模式1、共享锁2、排它锁3、更新锁4、意向锁5、模式锁6、批量更新锁锁的兼...
    99+
    2022-11-13
  • 怎样浅析Sql server锁
    怎样浅析Sql server锁,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。锁有两种分类方法。(1) 从数据库系统的角度来看锁分为以下三种类型...
    99+
    2022-10-19
  • SQL Server的死锁说明
    目录一、了解死锁二、检测并结束死锁2.1、可能死锁的资源三、处理死锁四、最大限度地减少死锁4.1、以相同的顺序访问对象4.2、避免事务中的用户交互4.3、保持交易简短且在一个批次中4.4、使用较低的隔离级别4.5、使用基...
    99+
    2023-04-12
    SQL Server死锁说明 SQL Server死锁
  • SQL SERVER提交事务回滚机制
    1、回滚语句1: SET XACT_ABORT OFF BEGIN TRAN INSERT INTO score VALUES (101,90) INSERT INTO sc...
    99+
    2022-11-12
  • sql server中怎么排查死锁
    sql server中怎么排查死锁,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。死锁的四个必要条件:互斥条件(Mutual exclusi...
    99+
    2022-10-18
  • Sql Server中怎么监控死锁
    本篇文章给大家分享的是有关Sql Server中怎么监控死锁,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。死锁的xml文件如下:<dea...
    99+
    2022-10-18
  • SQL Server中如何减少死锁
    SQL Server中如何减少死锁,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。  减少SQLServer死锁的方法有哪些  如事务1的线程T...
    99+
    2022-10-18
  • SQL server备份和还原机制是怎样的
    这篇文章将为大家详细讲解有关SQL server备份和还原机制是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。  SQL server备份和还原组件为...
    99+
    2022-10-18
  • SQL Server可以锁定的资源类型
    SQL Server可以锁定的资源类型SQL Server可以锁定不同类型的资源。这些可以被锁定的资源类型包括:RIDs或键(keys)(行级别),页(pages),对象(objects)(例如,表),数据...
    99+
    2022-10-18
  • Sql Server中怎么查看被锁的表
    Sql Server中怎么查看被锁的表,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。查看被锁表:select&nbs...
    99+
    2022-10-18
  • SQL Server内部运行机制的原理是什么
    本篇文章给大家分享的是有关SQL Server内部运行机制的原理是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。(一)查询缓慢问题*,临时...
    99+
    2022-10-18
  • sql server怎么排查死锁优化性能
    本篇内容主要讲解“sql server怎么排查死锁优化性能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“sql server怎么排查死锁优化性能”吧!一.概述记得以前客户在使...
    99+
    2023-06-29
  • SQL Server中事务与锁的示例分析
    这篇文章将为大家详细讲解有关SQL Server中事务与锁的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一  概述在数据库方面,对于非DBA的程序员来...
    99+
    2022-10-18
  • sql server中意向锁的作用是什么
    本篇文章给大家分享的是有关sql server中意向锁的作用是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。  sql server中意向...
    99+
    2022-10-18
  • SQL Server中怎么实现一个自旋锁
    这期内容当中小编将会给大家带来有关SQL Server中怎么实现一个自旋锁,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。为什么我们需要自旋锁?用闩锁同步多个线程间数据结构...
    99+
    2022-10-18
  • sql server中死锁排查的示例分析
    这篇文章主要介绍sql server中死锁排查的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!死锁的四个必要条件:互斥条件(Mutual exclusion):资源不能被共享...
    99+
    2022-10-18
  • Sqlite—锁机制
    https://blog.csdn.net/zhangsheng_1992/article/details/52598396 https://blog.csdn.net/xiyangyang8110/article/details/5216...
    99+
    2017-08-22
    Sqlite—锁机制
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作