【问题标题】:Prevent deadlock in read-committed SELECT防止读取提交的 SELECT 中的死锁
【发布时间】:2019-07-11 19:24:43
【问题描述】:

我正在从第三方提供的业务系统中提取数据以用于报告。我正在使用从连接源系统中的多个表的 SSIS 数据流任务源组件发出的单个 SELECT 语句来创建我想要的数据集。我们正在使用默认的已提交读隔离级别。

令我惊讶的是,我经常发现这个提取查询是死锁并被选为受害者。我不认为读取提交事务中的 SELECT 可以做到这一点,但根据这个 SO 回答它可能的:Can a readcommitted isolation level ever result in a deadlock (Sql Server)?

通过使用跟踪标志 1204 和 12222,我确定了冲突的语句,以及有问题的对象和索引。本质上,争用是针对其中一个表的主键中的数据页。我需要使用其键上的连接从该表中提取(因此我要取出 S 锁),冲突语句正在执行 INSERT 并请求索引数据页上的 IX 锁。

(旁注:上面的 SO 讨论了 非聚集 索引发生的这个问题,但这似乎发生在聚集 PK 中。至少,这是我认为基于我的事件日志中的死锁信息和“关联ObjectId”属性的解释。)

这是我的限制:

  1. 冲突语句位于第三方提供的加密存储过程中,作为现成软件的一部分。无法获取或更改明文代码。
  2. 我不想使用脏读,因为我需要提取的数据来保持其完整性。
  3. 我不清楚重组我的提取查询如何或是否可以防止这种情况发生。锁在我最感兴趣的表的 PK 上,我看不到使用 PK 的任何替代方法。
  4. 我不介意我的提取查询成为受害者,因为我更喜欢这样做而不是中断源系统的操作使用。但是,这确实会导致 SSIS 执行失败,所以如果必须这样,我想要一种更干净、更优雅的方式来处理这种情况。

任何人都可以建议最好的方法来防止死锁,或者如果没有,那么更好地处理错误?

【问题讨论】:

  • 考虑使用快照隔离事务来避免数据读取和死锁。
  • 哪些特定的 SSIS 组件,即 OLE DB 源/目标、执行 SQL 任务等会导致死锁?
  • 感谢@DanGuzman,阅读我认为它会起作用,尽管我认为它可能会影响业务系统对更改数据库设置的支持(即使设置快照隔离应该不影响现有查询)以及对 tempdb 大小的影响。
  • @userfl89 是的,它是 DFT 中的 OLE DB 源。死锁中涉及的另一个查询来自第三方应用程序,而不是来自 SSIS。
  • @GreatApe,是的,打开数据库 ALLOW_SNAPSHOT_ISOLATION 会增加 tempdb 的使用率并产生每行 14 字节的额外开销。在许多情况下,收益大于开销。

标签: sql-server tsql ssis deadlock read-committed


【解决方案1】:

我在这里的假设是您正试图插入到您从中选择的同一个表中。如果不是,那么数据流选项卡的屏幕截图将有助于确定问题。如果是,那么你很幸运——我以前遇到过这个问题。

为数据流添加一个排序,因为这是一个完全阻塞的转换(参见下面的阻塞转换)。这意味着在允许任何数据向下传递到目的地之前,将需要 SELECT 完成将所有数据加载到管道缓冲区中。否则,当表/索引上存在锁定时,SSIS 会尝试插入数据。您也许可以在此处通过索引策略获得创意(我没有尝试过)。但是,完全阻塞的转换可以解决问题,并消除对表的任何额外索引的需要(以及由此产生的开销)。

注意:从不在从表中选择数据时使用 NOLOCK 查询提示来解决此问题。我从未尝试过,也不打算这样做。您(皇室成员)冒着将未提交的数据摄入 ETL 的风险。

参考:

https://jorgklein.com/2008/02/28/ssis-non-blocking-semi-blocking-and-fully-blocking-components/

【讨论】:

  • 嗨@j-weezy 谢谢你的回复,虽然我认为你误解了这个场景。只有 my SELECT 来自 SSIS。冲突的 INSERT 是由第三方应用程序发出的(参见约束 1)
  • @GreatApe 我会联系第 3 方应用程序提供商并让他们知道,因为是他们的代码导致了问题。
  • 我怀疑他们会通过对他们的数据库执行查询来认为我是导致问题的人:)
  • @GreatApe 你任由他们摆布,因为存储过程是加密的,而且它是他们的数据库——它也可能是一个黑匣子。但是,您在第 3 段中关于争用的评论表明 SELECT 和 INSERT 指向同一个表。否则,如果其他客户端正在访问该供应商的数据库,那么这也可能导致死锁。我还是会伸手去问。
猜你喜欢
  • 1970-01-01
  • 2017-03-27
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多