SQL Server 在同一个表上发生死锁

2024-01-22

我们的应用程序中存在死锁情况的问题。在过去的几天里,我阅读了很多有关阻塞、锁定和死锁的内容,试图了解问题并解决问题。

现在,当我阅读有关死锁的错误日志信息时,我无法理解这种情况是如何存在的。看看这个(我已经重命名了表名,但重要的是日志消息中名为 OurTable 的表名):

deadlock-list
deadlock victim=process1e2ac02c8
process-list
    process id=process1e2ac02c8 taskpriority=0 logused=0 waitresource=OBJECT: 11:290100074:0  waittime=704 ownerId=3144354890 transactionname=SELECT lasttranstarted=2011-12-01T14:43:20.577 XDES=0x80017920 lockMode=S schedulerid=6 kpid=7508 status=suspended spid=155 sbid=0 ecid=0 priority=0 trancount=0 lastbatchstarted=2011-12-01T14:43:20.577 lastbatchcompleted=2011-12-01T14:43:20.577 clientapp=.Net SqlClient Data Provider hostname=DE-1809 hostpid=5856 loginname=2Ezy isolationlevel=read committed (2) xactid=3144354890 currentdb=11 lockTimeout=4294967295 clientoption1=673185824 clientoption2=128056
     executionStack
      frame procname=.dbo.RetrieveSomething line=23 stmtstart=1398 stmtend=3724 sqlhandle=0x03000b0030d42d645a63e6006a9f00000100000000000000
         select
            Col1
            ,Col2
            ,(
                SELECT TOP(1)
                    Col1
                FROM
                    OurTable2 AS C
                        JOIN OurTable AS ETC ON C.Id = ETC.FKId
                            AND E.Id = C.FKId
                ORDER BY ETC.Col2
            ) AS Col3
        from OurTable3 AS E
    process id=process2df4894c8 taskpriority=0 logused=0 waitresource=OBJECT: 11:290100074:0  waittime=9713 ownerId=3144330250 transactionname=INSERT EXEC lasttranstarted=2011-12-01T14:43:11.573 XDES=0x370764930 lockMode=S schedulerid=13 kpid=4408 status=suspended spid=153 sbid=0 ecid=0 priority=0 trancount=1 lastbatchstarted=2011-12-01T14:43:11.573 lastbatchcompleted=2011-12-01T14:43:11.573 clientapp=.Net SqlClient Data Provider hostname=DE-1809 hostpid=5856 loginname=2Ezy isolationlevel=read committed (2) xactid=3144330250 currentdb=11 lockTimeout=4294967295 clientoption1=673185824 clientoption2=128056
     executionStack
      frame procname=adhoc line=1 sqlhandle=0x02000000ba6cb42612240bdb19f7303e279a714276c04344
         select
            Col1
            , Col2
            , Col3
            , ISNULL(
                (select top(1)
                    E_SUB.Col1 + ' ' + E_SUB.Col2
                    from OurTable3 as E_SUB 
                        inner join OurTable2 as C on E_SUB.Id = C.FKId
                        inner join OurTable as ETC on C.Id = ETC.FKId
                as Col3
        from OurTable4
            inner join dbo.OurTable as ETC on Id = ETC.FKId  
    process id=process8674c8 taskpriority=0 logused=0 waitresource=OBJECT: 11:290100074:5  waittime=338 ownerId=3143936820 transactionname=INSERT lasttranstarted=2011-12-01T14:38:24.423 XDES=0x1ecd229f0 lockMode=X schedulerid=7 kpid=12092 status=suspended spid=124 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2011-12-01T14:38:23.027 lastbatchcompleted=2011-12-01T14:38:23.013 clientapp=.Net SqlClient Data Provider hostname=DE-1809 hostpid=5856 loginname=2Ezy isolationlevel=read committed (2) xactid=3143936820 currentdb=11 lockTimeout=4294967295 clientoption1=673185824 clientoption2=128056
     executionStack
      frame procname=.dbo.UpsertSomething line=332 stmtstart=27712 stmtend=31692 sqlhandle=0x03000b00bbf2a93c0f63a700759f00000100000000000000
            insert into dbo.OurTable
            (
                Col1
                ,Col2
                ,Col3
            )
            values
            (
                @Col1
                ,@Col2
                ,@Col3
            )
       resource-list
        objectlock lockPartition=0 objid=290100074 subresource=FULL dbid=11 objectname=dbo.OurTable id=lock16a1fde80 mode=X associatedObjectId=290100074
         owner-list
         waiter-list
          waiter id=process1e2ac02c8 mode=S requestType=wait
        objectlock lockPartition=0 objid=290100074 subresource=FULL dbid=11 objectname=dbo.OurTable id=lock16a1fde80 mode=X associatedObjectId=290100074
         owner-list
          owner id=process8674c8 mode=X
         waiter-list
          waiter id=process2df4894c8 mode=S requestType=wait
        objectlock lockPartition=5 objid=290100074 subresource=FULL dbid=11 objectname=dbo.OurTable id=lock212f0f300 mode=IS associatedObjectId=290100074
         owner-list
          owner id=process1e2ac02c8 mode=IS
         waiter-list
          waiter id=process8674c8 mode=X requestType=wait

我读这篇文章的方式是:

spid 155 正在等待 OurTable 上的共享表锁 (spid 124 持有冲突的 X 锁)

spid 153 正在等待 OurTable 上的共享表锁 (spid 124 持有冲突的 X 锁)

spid 124 正在等待 OurTable 上的独占表锁 (spid 155 持有冲突的 IS 锁)

我的问题是这是如何发生的。两个会话同时持有整个表的一把锁。我认为通常的死锁是两个或多个会话持有不同资源的锁并互相等待。但这里的锁是在同一个资源上。它不是索引上的锁,而是表上的锁。这个错误在我们的应用程序中很常见,某些锁必须是第一个被请求的锁,如果整个表上已经有锁,为什么还要接受第二个锁?

任何人都可以暗示可能出了什么问题,或者任何人经历过类似的僵局?


经过更多的搜索和测试后,我非常有信心可以对自己的问题给出正确的答案。

我必须感谢 Martin Smith,他指出等待资源是不同的,为我指明了正确的方向。

正如马丁在评论中所写,等待资源为:11:290100074:0 和 11:290100074:5。 搜索后发现,如果您在具有 16 个或更多 CPU 的计算机上运行 Sql Server R2,则 Sql Server 能够使用称为锁分区 http://msdn.microsoft.com/en-us/library/ms187504.aspx.

这篇文章除其他外还提到:

仅在单个上获取 NL、SCH-S、IS、IU 和 IX 锁定模式 分割。

在我的例子中,spid 155 在行或页上放置了一个共享锁,因此在对象上放置了一个预期的共享锁,并且使用锁分区功能,这恰好位于分区 id 5 上。

同时spid 124需要使用排他锁锁定完整对象,因此需要在所有分区上放置X锁。

共享(S)、排他(X)以及NL以外模式的其他锁, 必须在所有以以下开头的分区上获取 SCH-S、IS、IU 和 IX 分区 ID 0 及以下分区 ID 顺序。

当它到达分区 id 5 时,它被告知 spid 155 持有 IS 锁,并且需要等待该锁被释放。

现在当 spid 124 正在等待 IS 锁被释放时锁升级 http://msdn.microsoft.com/en-us/library/ms184286.aspx发生在 spid 155 上,它请求表上的共享锁。这意味着它需要在 id 0 开始的所有分区上放置 S 锁。但是在 id 0 上它立即就碰壁了,因为 spid 124 已经在该分区上持有排他锁。这就是僵局的原因。

我不能保证 100% 这是准确的答案,但我很确定我即使不是 100% 正确,至少也接近答案。

解决方案?出色地。锁定分区功能无法关闭,但另一方面您可以控制锁升级 http://msdn.microsoft.com/en-us/library/ms184286.aspx具有不同的事务级别以及 alter table 语句中的不同选项。

我将继续调查为什么查询会强制锁定升级,因为我相信我的特定情况下的解决方案是以某种方式调整查询以使其不升级。至少在使用上述工具之前我会尝试一下。

希望这个答案可以帮助其他遇到类似问题的人。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL Server 在同一个表上发生死锁 的相关文章

  • 按小时拆分日期/时间数据并将日期/时间范围展开为行

    我正在尝试使用 SQL Server 将一系列日期 时间数据扩展为多行 例如 我的数据看起来像 Date StartTime EndTime EmployeeID ShiftType 10 1 2019 8 30 00AM 4 57 00P
  • 如何在SQL Server数据库表列中存储图像[重复]

    这个问题在这里已经有答案了 我有一张名为FEMALE在我的数据库中 它有ID as Primary Key 它有一个Image column 我的问题是如何使用 SQL 查询存储图像 尝试一下 insert into tableName I
  • sql server GO 相当于 oracle

    我正在为 Oracle 编写迁移脚本 我需要更改表结构 然后用数据填充它 我想先进行结构更改 然后再进行数据更改 在 SQL Server 中我会使用GO分离批次 是否有 SQL ServerGOOracle 中的等效命令 It s and
  • SQL Server Express 到 .mdf 文件的连接

    两部分问题 我使用 VS 2015 Update 3 创建了一个 ASP NET MVC 5 应用程序 我在本地计算机上完成了该项目 突然 我无法再通过 SQL Server 对象资源管理器连接到 mdf数据库文件并出现以下错误 无法打开数
  • Postgres、更新和锁定顺序

    我正在研究 Postgres 9 2 有 2 个更新 每个更新都有自己的事务 一个看起来像 UPDATE foo SET a 1 WHERE b IN 1 2 3 4 另一个也类似 UPDATE foo SET a 2 WHERE b IN
  • SQL Server 相当于 MySQL 的 USING

    在 MySQL 中 当您连接不同表中具有相同名称的列时 可以在连接中使用关键字 USING 例如 这些查询产生相同的结果 SELECT FROM user INNER JOIN perm USING uid SELECT FROM user
  • SQL Server 转换选择一列并将其转换为字符串

    是否可以编写一条从表中选择列并将结果转换为字符串的语句 理想情况下 我希望有逗号分隔的值 例如 假设 SELECT 语句看起来像这样 SELECT column FROM table WHERE column lt 10 结果是一列包含值的
  • 将多行合并为一行并根据行数附加列

    我正在尝试将同一个表的多行合并为一个 我有一个像这样的示例表 Col1 Col2 Col3 Col4 Col5 Col6 1 BH1 CB 12 CC CC Conveyor Mal 1 BH1 CB 104 ZC ZC Full Emp
  • Spring Boot MSSQL Kerberos 身份验证

    目前在我的春季靴子中application properties文件中 我指定以下行来连接到 MSSql 服务器 spring datasource url jdbc sqlserver localhost databaseName spr
  • 从一个sql服务器选择到另一个sql服务器?

    我想将一台服务器 Data Old S1 中的一个表 T1 在 DB1 中 中的数据选择到另一台服务器 Data Latest S2 中的另一个表 T2 在 DB2 中 中的数据 我怎样才能做到这一点 请注意服务器的命名方式 查询也应该考虑
  • PHP DBlib PDO 问题

    我正在尝试通过 php 连接到 MSSQL 服务器 但我的 pdo 连接给我带来了困难和我不太理解的错误 我在下面粘贴的代码一周前运行得很好 突然间它就停止了 没有任何人进行任何更改 我仍然可以连接到服务器并直接从命令行运行查询 但我在 p
  • 为什么查询优化器完全忽略索引视图索引?

    SQL 小提琴 http sqlfiddle com 6 d4496 1 http sqlfiddle com 6 d4496 1 数据是为您的实验预先生成的 有一个明显的表格 CREATE TABLE Entity ID int Clas
  • 在 C# 中将平面数据库结果集转换为分层对象集合

    我有一个数据库查询 它以平面格式返回分层数据 例如客户 订单和订单项目 只是一个例子 我的数据不同 如何将其转换为分层对象集合 即客户对象的集合 其中每个客户对象都有订单对象的集合 每个订单对象都有订单项目对象的集合 这只是循环遍历每个项目
  • 该驱动程序未配置为集成身份验证

    尝试使用以下命令将我的 Java Web 应用程序与 MS SQL 服务器连接sqljdbc41 for jdk 1 8 这是数据库连接代码 Connection connection String url jdbc sqlserver l
  • 按两列的最小值排序

    I use SQL Server 2008 R2 我需要按两列的最小值对表进行排序 该表如下所示 ID integer Date1 datetime Date2 datetime 我希望我的数据按至少两个日期排序 以这种方式对该表进行排序的
  • 使用 t-sql 检索已过滤的存储过程列表

    我正在尝试获取 t sql 中的存储过程列表 我正在使用该行 exec sys sp stored procedures 我想过滤回结果 所以我只获取用户创建的存储过程 我想过滤掉 sp dt fn xp 以及其他所有我不感兴趣的系统存储过
  • 在 SQL Server SELECT 语句中使用 CASE 时消除 NULL

    我有一份大而混乱的报告要写 它连接了 5 个表 一个表中有一列用于多个不同的值 本质上是一个 标签 列 其中标签根据用户想要使用的各种元数据的类型以创造性的方式使用 因此 我对报告的查询返回 3 个几乎相同的行 仅 标签 列有所不同 例如
  • 内联表值 UDF 能否优于 SELECT 列列表中的等效标量 UDF?

    这个问题源于SQLServer 为什么要避免表值用户定义函数 https stackoverflow com questions 1081057 sqlserver why avoid table valued user defined f
  • 仅基于月份和年份的 SQL Server 日期比较

    我无法确定仅根据月份和年份比较 SQL 中的日期的最佳方法 我们根据日期进行计算 由于计费是按月进行的 因此该月的日期会造成更多障碍 例如 DECLARE date1 DATETIME CAST 6 15 2014 AS DATETIME
  • 'ExecuteReader 需要一个开放且可用的连接。连接的当前状态是打开'

    用 C 编写的相当大的 Web 应用程序不断抛出 2 个错误 ExecuteReader 需要一个开放且可用的连接 连接的当前状态是打开的 和 阅读器关闭时调用 Read 的尝试无效 这些错误是零星的 过去页面在大约 95 的情况下加载良好

随机推荐

  • 可见光谱的RGB值

    I need an algorithm or function to map each wavelength of visible range of spectrum to its equivalent RGB values Is ther
  • WinRT 替换 System.Environment.TickCount

    System Environment TickCount 的 WinRT 替代品是什么 它应该是可用的 因为它没问题 http msdn microsoft com en us library windows apps br205762 a
  • 如何在Python中检查一个数字的所有数字是否都是奇数?

    有人告诉我要解决一个问题 我必须找出全部由奇数组成的 4 位数字的个数 我尝试了以下 python 代码 new list A list which holds the numbers for a in range 1111 10000 f
  • 为什么我的 AJAX 函数多次调用回调?

    我制作了一个 ajax post 函数 当我调用它一次时 传递给它的回调函数最终会被调用 3 次 为什么回调会被多次调用 我正在尝试使用一种 模块 javascript 模式 该模式使用闭包将类似的功能包装在一个全局变量下 我的 ajax
  • Magento 多商店 URL 重写

    我们正在开发一个 Magento 网站 该网站有几个不同的商店 我们正在努力重写 url 以便当您位于特定商店时 商店名称会添加到 url 中 我们尝试了几种不同的方法 首先 在 系统 gt 配置 gt Web 中打开 将商店代码添加到 U
  • 变量的重用

    我正在开发的项目需要多次调用相同的方法 但参数不同 我可以使用相同的变量还是必须声明另一个变量 例如 HttpWebRequest req HttpWebRequest WebRequest Create domains ServiceLo
  • 部署 Django/Heroku 时 PySFTP 失败,并显示“No hostkey for host X found”

    我正在尝试部署一个 Django Web 应用程序 该应用程序使用 pysftp 通过某些视图访问 SFTP 服务器 这个东西在本地开发中运行得很好 但是当尝试在 Heroku 上进行第一次部署时 下面的回溯似乎以错误结束 似乎我需要配置主
  • 从命令行将 mysql 数据库转储为纯文本 (CSV) 备份

    我想避免 mysqldump 因为它以只方便 mysql 读取的形式输出 CSV 似乎更通用 每个表一个文件就可以 但如果 mysqldump 有优点 我会洗耳恭听 另外 我想要一些可以从命令行 linux 运行的东西 如果那是一个 mys
  • 我应该检查 malloc() 是否成功吗?

    应该在每次之后检查一次malloc 如果成功了 有没有可能malloc 失败 然后会发生什么 在学校我们被告知我们应该检查 即 arr int malloc sizeof int x y if arr NULL printf Error A
  • 单击 - 如何在带有位置参数的命令下嵌套子命令?

    我正在转移一个开源项目的 https github com ManimCommunity manim从 argparse 到 CLI 单击 目前该库允许以下内容CLI 使用模式 https docs manim community en l
  • 如何防止字符指针缓冲区溢出?

    i e int function char txt sprintf txt select from s table How do I set last char in buffer to NULL here 因此 如果表中的文本长度为 50
  • createElement() +appendChild()——DOM 方法

    我试图在 div 内创建一个 a 元素 并在该 a 元素中添加 div 元素中已存在的 img 图像 但是 我对此表示怀疑 因为以下代码不起作用 document querySelectorAll card forEach function
  • 在 C# 中按按钮进行表单验证的最简单方法?

    我有一个基于 C 的 WinForms 应用程序 其中有很多菜单 每个菜单都有多个用于用户输入的控件 所有表单都有 OK 按钮 这些按钮对用户给出的输入进行处理 例如 当用户按下 确定 按钮时 我必须对所有这些控件进行验证 检查输入的字符串
  • Scala:模拟伴随对象和模型与服务方法

    我看到了多个关于如何模拟伴随对象的问题 经常提到的答案是使用 scalamock 但根据doc http scalamock org对于版本 3 模拟伴生对象仍标记为将来使用 那么模拟伴生对象的方法是什么呢 如果没有 是否有比我已经启用测试
  • Graphics.CopyFromScreen [Web 应用程序] + 句柄无效

    我正在使用下面的代码来打印我的网页的屏幕 using Bitmap bitmap new Bitmap 620 850 using Graphics g Graphics FromImage bitmap g CopyFromScreen
  • 批处理文件从exe获取返回值

    我写了一个简单的C程序DOW exe 返回值是星期几 我的批处理文件需要这个 那么我该怎么做 如何获得返回值 DOW exe 涂 我的批处理文件 不起作用 set day DOW exe echo day Use ERRORLEVEL Li
  • 将 Maven 存储库添加到 build.gradle

    我在 Android Studio 中向 build gradle 添加了自定义 Maven 存储库 但未找到依赖项 Maven 存储库和依赖项
  • 为什么 Java 允许类型不安全的数组赋值?

    一般来说 Java 可以被认为是一种类型安全的语言 我知道泛型存在一些缺陷 但我最近遇到了一个以前从未遇到过的问题 分解它 Object objects new Integer 10 objects 0 Hello World 不会像预期的
  • 涉及错误“赋值之前引用的局部变量...”的简单循环[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 Python 我对此进行了很多研究 但作为初学者 我不理解解决方案 更不用说将它们应用于我的简单问题 def min max xs
  • SQL Server 在同一个表上发生死锁

    我们的应用程序中存在死锁情况的问题 在过去的几天里 我阅读了很多有关阻塞 锁定和死锁的内容 试图了解问题并解决问题 现在 当我阅读有关死锁的错误日志信息时 我无法理解这种情况是如何存在的 看看这个 我已经重命名了表名 但重要的是日志消息中名