我正在从第三方提供的业务系统中提取数据以用于报告。我正在使用从SSIS数据流任务源组件发出的单个SELECT语句,该语句跨源系统中的多个表联接以创建所需的数据集。我们正在使用默认的已提交读隔离级别。
令我惊讶的是,我经常发现此提取查询陷入僵局并被选为受害者。我不认为在读提交的事务中执行SELECT可以做到这一点,但是根据这样的答案, 是可能的:Can a readcommitted isolation level ever result in a deadlock (Sql Server)?
通过使用跟踪标志1204和12222,我确定了冲突的语句以及相关的对象和索引。本质上,争用是在其中一个表的主键中的数据页上进行的。我需要使用其键上的联接从该表中提取(因此我要取出S锁),冲突的语句正在执行INSERT并正在索引数据页上请求IX锁。
(请注意:上面的SO谈论的是非集群索引出现的这个问题,但这似乎是在集群PK中发生的。至少,基于我的看法,解释事件日志中的死锁信息和“ associatedObjectId”属性。)
这是我的限制条件:
任何人都可以建议一些方法来最好地防止死锁,或者如果没有,则可以更好地处理错误?
答案 0 :(得分:0)
我在这里的假设是,您试图将INSERT插入要选择的同一表中。如果否,则数据流选项卡的屏幕快照将有助于确定问题。如果是,那么您很幸运-我之前遇到过这个问题。
向数据流添加排序,因为这是完全阻塞的转换(有关阻塞转换,请参见下文)。这意味着在允许任何数据向下传递到目的地之前,将需要SELECT将所有数据完全加载到管道缓冲区中。否则,当表/索引上有锁时,SSIS尝试插入数据。您可能可以在这里通过索引策略发挥创意(我还没有尝试过)。但是,完全阻塞的转换将达到目的,并且消除了对该表添加任何其他索引的需求(以及随之而来的开销)。
注意:从表中选择数据时,从不不使用NOLOCK查询提示来解决此问题。我从来没有尝试过,也没有打算。您(贵族贵族)冒着将未提交的数据吸收到ETL中的风险。
参考:
https://jorgklein.com/2008/02/28/ssis-non-blocking-semi-blocking-and-fully-blocking-components/