Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

这篇具有很好参考价值的文章主要介绍了Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

我有一个People表,有三行数据:
Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

如果我们没详细了解数据库事务执行加锁的过程中,会不会有这样一个疑问:如下的这段 SQL 开启了事务,并且在事务中进行了更新和查询操作。

BEGIN TRAN 
	update People set Name='张三' where id=1;
	
	select * from People where id=1;
commit tran

我们知道sql server数据库的默认事务级别是READ COMMITTED(已提交的读取),我们再看一下已提交读事务隔离级别描述:

允许事务读取另一个事务以前读取(未修改)的数据,而不必等待第一个事务完成。 SQL Server数据库引擎将保留 (对所选数据) 获取的写入锁,直到事务结束,但读取锁将在执行 SELECT 操作后立即释放。 这是SQL Server数据库引擎默认级别。

那么我们在READ COMMITTED 隔离级别下更新People表数据库,按照这个逻辑在id=1的数据行上添加排它锁(X锁)并等到事务提交后才会释放锁。
但是事务继续执行查询,在READ COMMITTED隔离级别下 Select 会对查询数据施加共享锁(S锁)。因为有排它锁,所以查询无法获得共享锁需要等待排它锁释放,如果按照这个逻辑的话这个事务自身就死锁无法执行了。

但这个事务还是会正常执行完成,针对这个疑问,那么我们看下数据库的事务和锁:

数据库引擎隔离级别

ISO 标准定义了以下隔离级别,SQL Server数据库引擎支持所有这些隔离级别:

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

Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!
SQL Server数据库引擎使用不同的锁模式锁定资源,这些模式确定并发事务如何访问资源。

T-SQL 设置事务隔离级别,只对当前会话连接一直有效

SET TRANSACTION ISOLATION LEVEL
    { READ UNCOMMITTED
    | READ COMMITTED
    | REPEATABLE READ
    | SNAPSHOT
    | SERIALIZABLE
    }

锁模式

下表显示了SQL Server数据库引擎使用的资源锁模式。

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

锁兼容性

锁兼容性控制多个事务能否同时获取同一资源上的锁。 如果资源已被另一事务锁定,则仅当请求锁的模式与现有锁的模式相兼容时,才会授予新的锁请求。 如果请求锁的模式与现有锁的模式不兼容,则请求新锁的事务将等待释放现有锁或等待锁超时间隔过期。 例如,没有与排他锁兼容的锁模式。 如果具有排他锁(X 锁),则在释放排他锁(X 锁)之前,其他事务均无法获取该资源的任何类型(共享、更新或排他)的锁。 另一种情况是,如果共享锁(S 锁)已应用到资源,则即使第一个事务尚未完成,其他事务也可以获取该项的共享锁或更新锁(U 锁)。 但是,在释放共享锁之前,其他事务无法获取排他锁。

下表显示了最常见的锁模式的兼容性。
Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

查看执行时锁的情况

通过锁的兼容性模式我们知道在id=1的行上添加了排它锁,那么它就无法再接收任何锁,那我们调试这个事务看看锁的情况。
Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

我们调试到第3行,这个时候看下锁的情况,此时事务添加了key(行)排它锁X锁,page(页)和object(表)添加了意向排它锁IX锁

SELECT 
resource_type,
resource_database_id,
resource_description,
request_mode,
request_type,
request_session_id,
request_owner_type,
request_owner_id,
lock_owner_address
FROM sys.dm_tran_locks where request_owner_type='transaction'

Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

然后我们再继续调试到第4行,此时还没提交事务,排它锁X依然存在,但是没有S锁。

Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

我们知道在读提交事务隔离级别下,S锁是使用完了就释放的,所以我们用SQL Server Profiler来监视下锁的情况,设置监控的项为lock,然后设置筛选条件。

Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!
Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

上面我已经将 张三1 改为了 张三,我们再将 张三 改回 张三1,并启动监控。

BEGIN TRAN 
	update People set Name='张三1' where id=1;
	select * from People where id=1;
commit tran

Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

可以看到事务 transactionid=30010685 的锁监控 :

  • 首先申请IX更新意向锁(object,page) 准备更新,然后获得行上的X排它锁进行更新,更新后释放了行锁和page锁(EventClass= Lock:released,Mode=0-null)。
  • 等查询时申请page页IS意向读取锁,并获得行S锁读取数据后释放行锁和page页锁。
  • 最后还有几个顺序释放,依次是key、page、Object,这里恰好和上面调试还没提交事务时查询sys.dm_tran_locks的锁情况一样,也就是说事务提交后依次又进行了一遍释放。

通过上面我们得出结论,事务里面并不是取得了X锁要等事务结束后才释放,在事务执行过程中也是有释放的,只是事务还保持着对于锁在事务层面的记录,防止其它事务并发(这里是我推断的,没找到相关文献说明)。
所以事务是在锁上更宏观的逻辑隔离,事务隔离级别只是在业务上保证数据符合隔离级别预期,至于事务中如何控制锁是基于数据库内在设计,而不能通过事务的描述去推断锁过程。

我查阅网上很多博文和官方资料都是讲事务和锁概念,有时候结合两种也是模棱两可看不出什么强联系,没有讲事务执行过程中锁是如何变化的,不知道我这篇推论是否正确,欢迎指正。

再次验证

我将事务隔离级别设置为REPEATABLE READ(可重复读),然后调试到commit行还没提交,我们看跟踪的锁和事务锁表dm_tran_locks查询的结果,按照REPEATABLE READ描述,select查询的S锁会在事务提交后释放,我们看看截图情况

Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

开启了SQL Server Profiler结果,查询id=3后S锁已经释放。

Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

再查dm_tran_locks表,表中依然显示事务获取了S锁,并且 resource_description=98ec012aa510 资源描述和上面跟踪是对应的。
Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

最后我们执行完调试,跟踪锁显示又按照顺序释放了一遍锁

Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!文章来源地址https://www.toymoban.com/news/detail-427938.html

到了这里,关于Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SQL Server数据库使用SQL Server代理实现数据库自动备份

    在现实中,为了保证数据的安全和完整,防止人为错误和硬件故障等造成的数据丢失和损坏,就需要用到数据库的备份,不同的数据库方法有所差别,我这边主讲SQL Server数据库的备份和使用SQL Server代理作业实现数据库的定时备份。 目录 一、开启SQL Server代理 1、找到SQL Serv

    2024年02月09日
    浏览(83)
  • 【建议收藏】数据库 SQL 入门——事务(内附演示)

    🙋‍♂️作者简介:生鱼同学,大数据科学与技术专业硕士在读👨‍🎓,曾获得华为杯数学建模国家二等奖🏆,MathorCup 数学建模竞赛国家二等奖🏅,亚太数学建模国家二等奖🏅。 ✍️研究方向:复杂网络科学 🏆兴趣方向:利用python进行数据分析与机器学习,数学建模竞

    2023年04月23日
    浏览(41)
  • SQL Server数据库——创建数据库

    目录 一、界面方式创建数据库 1.1创建数据库xscj,数据文件和日志文件的属性按默认值设置  1.2在xscj数据库中增加文件xcsj1,其属性均取系统默认值  1.3在数据库xscj中增加一个名为myGroup的文件组。 1.4数据库的重命名  1.5数据库的删除  二、命令方式创建数据库 以创建学生管

    2024年02月01日
    浏览(67)
  • SQL Server 数据库安装教程SQL Server 2017

    官网: SQL Server 下载 | Microsoft  软件版本看你自己需求啦,反正我是下了SQL Server 2017 评估版(试用180天,秘钥自己百度)  下载后,软件有点小,不是实际的安装包,只是安装导向包,在安装过程才下载实际的安装包:      要保持有网络,直接双击安装,选基本即可:  选好

    2024年02月05日
    浏览(93)
  • sql server数据库跟踪——SQL Server Profiler解析

    工具 : SQL Server Profiler这个工具是SQL Server数据库自带的语句执行跟踪工具,常使用于分析软件修改数据库时所执行的语句,适合用来研究软件运行数据库的原理。 打开方式: 本机安装了SQL server的话,都是自带的。直接去直接在【开始】-【程序】-搜索Profiler可找到【SQL Ser

    2024年04月16日
    浏览(140)
  • SQL Server2008数据库升级至SQL Server2012

    今天接到了一个需求,服务器上的数据库需要从SQL Server2008升级到2012。根据之前的经验,感觉是一个非常有意思的过程(事实上也是。这个过程也给了我一些触动与启发,因此,便记录了自己的踩坑过程以及解决方案,还有安装过程的体会。 启动SQL Server2012的安装引导程序,

    2024年02月05日
    浏览(89)
  • 数据库实验:SQL的数据更新

    再次书接上文,sql基础的增删改查 (1) 掌握DBMS的数据查询功能 (2) 掌握SQL语言的数据更新功能 (1) update 语句用于对表进行更新 (2) delete 语句用于对表进行删除 (3) insert 语句用于对表进行插入 (1) 熟练掌握SQL的数据更新语句INSERT、UPDATE、DELETE (2) 写出实验报告 认真阅读S_T.sql,理

    2024年02月05日
    浏览(54)
  • SQL Server数据库使用

    SQL Server 2008 R2的安装和使用 安装前的准备 安装过程 1)安装所选功能 2)安装的类型:默认或命名实例 3)服务账户 4)身份验证模式 5)排序规则设置 6)开始安装 7)完成安装 验证数据库安装成功 【开始】|【程序】中可以看到Microsoft SQL Server 2008的程序组 启动和停止数据库

    2024年02月11日
    浏览(77)
  • SQL Server数据库管理

    数据库登录——使用两种方式均可登录数据库:windows和sqlserver身份验证方式两种。  数据库的使用和管理 步骤一:创建数据库 1)新建数据库,数据库名为book,初始大小都配置为3,自动增长与路径都为默认,点击确定   步骤二:查看主数据与日志文件(查看C:Program Files

    2024年02月13日
    浏览(70)
  • Sql server数据库安装

    以sql server2014数据库为例 sql server数据库安装需要注意两点: 1.不使用从镜像中拷贝出的压缩包安装会报错,提示缺少trin_aide.cab和vs_shell.cab文件 2.sql server2014数据库安装前需要安装.net Framework 3.5 各个版本sql server数据库情况: 1.sql server2008 R2数据库提示需要.net Framework 3.5。但不

    2024年02月09日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包