AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 132410
Accepted
saroff
saroff
Asked: 2016-03-17 07:46:59 +0800 CST2016-03-17 07:46:59 +0800 CST 2016-03-17 07:46:59 +0800 CST

长时间运行的 SELECT 查询作为 SQL SERVER 上的 DELETE 的死锁牺牲品失败 - 为什么以及如何避免这种情况?

  • 772

首先 1 个线程从表中选择大量数据。

然后,在 SELECT 查询尚未完成之前,另一个线程从该表中删除数据。

它会导致 SELECT 查询失败,错误为 errorCode=1205 sqlState=40001 并显示发生死锁的消息。

我认为第二个事务必须等到第一个事务完成,或者第一个事务必须返回数据而没有第二个事务所做的更改。我怎样才能避免这种情况?

我无法更改交易的顺序或以某种方式控制它们(应用程序的用户很多,他们可以随时以任何顺序做任何他们想做的事情)。为什么会这样?

查询看起来是这样的(我稍微混淆了它们):

SELECT distinct P.pID, (LastNAME+' '+FirstName+' '+SurName) as NAME, 'person' as Type, CA.OrgName, PC.personemail as Email
FROM Persons P
INNER JOIN WORK PW ON (P.mainwork = PW.pwId)
INNER JOIN CONTACT PC ON (PC.pID = P.pID)
LEFT OUTER JOIN ORG CA ON (CA.orgId = PW.orgId)
WHERE (P.Status = ?)

和

DELETE FROM persons WHERE id = 1234
sql-server transaction
  • 1 1 个回答
  • 8359 Views

1 个回答

  • Voted
  1. Best Answer
    Ian_H
    2016-03-17T08:28:25+08:002016-03-17T08:28:25+08:00

    我认为第二笔交易必须等到第一笔交易完成

    基本上,这是不正确的。如果一次只有一个人可以对它做某事,那么您(或任何人)的数据库将不会非常有效。

    为什么会这样?

    简单地:

    一个 SELECT 查询在它正在查看的任何行上都使用共享锁,所以虽然它不会与另一个 SELECT 查询冲突,但它肯定会与来自 DELETE 的排他锁冲突。由于 SELECT 查询没有更新任何内容,它通常会成为死锁的受害者,因为它可能是回滚成本最低的。

    如果没有进一步的信息,无法说明为什么会在您所谈论的情况下特别发生这种情况。我将在最后添加一些死锁检测的链接,但我怀疑这不是问题的主要目的,所以......

    该怎么办?

    很难知道最适合您的方法是什么(没有更多信息)。您可能应该查看一下您的隔离级别。

    您可以使用 READ_COMMITTED_SNAPSHOT,但这可能会导致更多开销,或者使用 READ_UNCOMMITED/使用 NOLOCK 提示 - 我通常不喜欢这些选项,因为返回的数据可能实际上不是您想要的,但它们可能适合你的情况。很难确切地说什么是最好的,因为它取决于您的系统及其使用的许多不同变量。

    在这方面,您可以做的最好的事情是阅读有关隔离级别的信息,这些是一些类似的帖子/资源,可以让您开始并更详细地了解事情。

    MSDN - select 语句如何导致被选为死锁受害者?, SQL Server 中央, MSDN - 了解隔离级别

    但...

    不要急于进行更改,以便完成查询。更合适的探索途径可能是您自己的查询。

    为什么 SELECT 语句需要这么长时间才能运行?为什么经常从表中删除东西?也许一些简单的查询调优会让它们更快地完成并减少死锁的机会。或许您需要对您的数据库服务器进行一些一般性的性能调整(我不会在这里详细介绍,因为它已经离题很远了)。

    您必须确保您的查询适合业务目的,而不仅仅是“不惜一切代价完成”的查询,数据库首先是一种业务工具,需要解决这个问题(无论我们多么不喜欢这样)!

    只是继续更改隔离级别,甚至只是使用 NOLOCK,都会对您的数据库以及查询返回的确切结果产生重大影响——这可能会对业务产生影响。

    还...

    为了帮助检测死锁,请查看StackOverflow上的这篇文章并查看MSDN 站点上的死锁信息工具,该工具将解释如何使用跟踪标志来提供有关死锁的更多信息。

    最后...

    如果您将 SQL Server 版本放在您的帖子中,可以提供更具体的建议,以及有关 SELECT 查询到底是什么的更多详细信息(查看是否有任何可能导致它花费这么长时间并打开以被锁定) .

    • 6

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve