最近做性能优化时碰到下面的死锁问题,起初看到这个图感觉很诡异,无法理解,两个查询语句为啥会导致死锁呢?查询语句为啥会导致X(排他)锁的产生呢?最后在查阅了一部分资料之后,终于可以解释通了。
1. 首先,此图中两个Key Lock分别代表数据库表上的两个行各自的行锁,是两个锁,而不是一个锁。图中的两个事务执行的是相同的代码,在事务中,首先做了一个查询,最后对查询的数据进行了更新。因此,就可以理解图中X(排他)锁是因为事务中的更新语句导致的,而不是查询语句导致的(虽然右键两个事务显示的都是相同的查询语句)。
所以,此图的意思是事务762385持有下面方框对应的行X(排他)锁,正在申请上面方框对应的行S(共享)锁。而事务762460持有上面方框对应的行X(排他)锁,正在申请下面方框对应的行S(共享)锁。而X锁和S锁是不能同时获得的,因此就发生了等待死锁。
2. 再来看看查询语句为啥会导致申请S(共享)锁失败,查询语句的执行计划如下:可以看到查询语句使用主键生成的Clustered索引进行了全表扫描,因此它会导致与更新无关的行在扫描的过程当中也需要申请S(共享锁)。
3. 如何只申请需要更新行的S(共享)锁呢?因为我们的查询语句对应的的两个查询条件正好对应有一个索引,所以只需要修改查询语句,使得查询计划使用这个存在的索引,这样就可以达到目的了。但是这样会引入部分需要的字段无法在同一个查询语句中查出来。解决办法是,先通过这个修改的查询语句找到该行的主键,然后再通过主键找到整行,因为主键也不是进行全表扫描,只会申请更新行的S(共享)锁。执行计划如下:
4. 还有一种办法是将事务分为两个小的事务,一部分做查询,一部分做更新。这样就不会出现同一个事务既需要X(排他)锁,又需要S(共享)锁的情况,也可以避免死锁的发生。或者将此部分的逻辑进行顺序化,也可以避免死锁。
参考文档:
1. SQL Server Deadlock - Two SELECT Exclusive Locks on Exact Same Index and Key [closed]
此文遇到了类似的问题,但是无解。问题描述相对比较准确。
2. Locking in Microsoft SQL Server (Part 3 – Blocking in the system)
此文详细描述了持有X(排他)锁,申请S(共享锁)导致死锁的情况,和我们遇到的问题一致。
3. SQL Server上的一个奇怪的Deadlock及其分析方法
此文描述了类似的死锁问题,对于原因讲述的比较详尽,操作方法执行比较困难。因为如果打出所有的SQL Trace,会产生数百万条的记录,如何在这些记录当中找出死锁对应的两个事务对应的SQL Trace还是相当有困难的。可以考虑将生成的SQL Trace导入到一张数据库表中,在导入的过程当中每隔5分钟删除所有我们不需要的事务对应的SQL Trace。这样最终得到的SQL Trace会减少到不到一万行。
相关推荐
SQL Server上的一个奇怪的Deadlock及其分析方法 Deadlock是SQL Server中的一种常见问题,它会导致事务无法继续执行,影响系统的性能和可靠性。了解Deadlock的产生原因和分析方法是非常重要的。本文将详细介绍SQL ...
### SQL Server 中的阻塞与死锁 #### 一、SQL Server事务的ACID特性 在探讨SQL Server中的阻塞和死锁之前,我们首先需要理解事务的基本特性——ACID特性,即原子性(Atomicity)、一致性(Consistency)、隔离性...
With this hands-on guide, you'll gain a solid understanding of T-SQL and good programming practices through the right balance of conceptual and practical content. Learn the steps required to develop ...
Key range locks are similar to row locks on index keys (whether clustered or not). The locks are placed on individual keys rather than at the node level. The hash value consists of all the key ...
操作系统教学课件:ch07-Deadlock-1pp.pdf
With SQL Deadlock Detector, you can: Monitor and detect long-running locks and deadlocks 24/7 Identify blocking SQL code, locked objects and deadlock victims with pinpoint accuracy Accelerate system ...
### SQL Server 死锁排查与解决方法 #### 一、SQL Server Profiler 监控数据库死锁 在处理SQL Server数据库中的死锁问题时,一个非常实用的工具就是SQL Server Profiler。它可以帮助我们捕捉到数据库运行过程中的...
SQL Server 2005/2008 Express Profiler 是微软SQL Server数据库管理系统中一个强大的性能监视工具,尤其适用于SQL Server 2008 Express版本。它允许开发者和DBA(数据库管理员)深入地洞察数据库系统的运行情况,...
4. Planning for and Installing SQL Server [加入我的離線書架] . SQL Server Editions . Hardware Guidelines . Hardware Components . The Operating System . The File System . Security and the User ...
在SQL Server数据库管理中,死锁是一个常见的性能问题,它发生在两个或多个事务相互等待对方释放资源时。本文将深入探讨如何使用SQL Server Profiler工具来监视和分析死锁,以便更好地理解和解决这类问题。 首先,...
在SQL Server中,有多种类型的锁,包括共享锁(Shared Locks)、排他锁(Exclusive Locks)、更新锁(Update Locks)和行级锁定(Row-Level Locking)。共享锁允许多个事务同时读取同一数据,但阻止任何写操作;排他...
5. **定期检测和中断死锁**:SQL Server提供了一个名为`DEADLOCK_PRIORITY`的选项,允许为事务指定优先级,当发生死锁时,优先级低的事务会被强制回滚。此外,SQL Server自带的死锁检测机制也会自动发现并解决死锁,...
在介绍SQL Server数据库事务锁机制之前,首先需要了解锁的概念。锁是网络数据库中的一个非常重要的概念,主要用于在多用户环境下保证数据库的完整性和一致性。锁通过指示某个用户(即进程会话)已经占用了某种资源,...
在SQL Server数据库管理系统中,死锁是常见的并发问题,它发生在两个或多个事务相互等待对方释放资源,导致它们都无法继续执行。"SQLServer自动杀死死锁进程"这一话题旨在探讨如何配置SQL Server来自动检测并解决...
### SQL Server 2005 SQL Profiler 使用详解 #### 1. 概述 SQL Server 2005 的 SQL Profiler 是一款强大的工具,主要用于监控 SQL Server 的活动和性能。它能够帮助数据库管理员(DBA)、开发人员以及测试工程师...
在SQL Server 2008中,锁机制是数据库管理系统(DBMS)为了确保数据的一致性和完整性,以及实现多用户并发访问时的一种关键机制。它通过控制对数据的访问来防止并发操作间的冲突,从而避免数据不一致的情况。本文将...
在SQL SERVER 2005中,Alerts、Jobs、Traces以及计数器是监控数据库健康状况和性能的关键工具。本文将详细介绍如何综合运用这些功能来有效地监控数据库运行状态,并利用收集的数据进行深入分析。 首先,我们来看...
哲学家问题是一个经典的多线程同步问题,由计算机科学家Edsger W. Dijkstra提出,用以探讨死锁的可能性和避免方法。在这个实现中,我们关注的是如何避免五位哲学家在用餐时出现死锁的情况。 哲学家问题的场景是这样...