【问题标题】:deadlock transaction - communication buffer resources死锁事务 - 通信缓冲区资源
【发布时间】:2012-11-03 12:59:56
【问题描述】:

我想获得有关改进导致 sql 服务器返回死锁消息的设置的建议。我有多个线程应用程序,它实际上使用 TaskParallel 库,每个任务将使用一个存储过程从表中选择一个 id 以用于其处理。我立即在同一语句中从表中删除了该 ID,我认为这就是导致死锁的原因。该表由一列没有索引的唯一 ID 组成。我曾想过定期进行批量删除,但这意味着要在多台服务器上保存已用 id 的计数。

这是我的 sql 存储过程:

   CREATE PROCEDURE [dbo].[get_Ids]
   @id nvarchar(20) OUTPUT

    AS

    BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
   SET NOCOUNT ON;

       Select top 1 @id = siteid from siteids 
       delete siteids where siteid = @id



   END

有没有更好的方法来做到这一点?我的流程运行得非常快,我曾经从 webrequest 服务请求此 ID,但这需要 3 秒。

【问题讨论】:

    标签: sql-server-2008 database-deadlocks


    【解决方案1】:

    可以尝试的一些事情: 也许尝试向数据库提示您将删除您刚刚选择的记录,这样它就会尽早获得锁定。为此,您需要将整个过程包装在事务中,然后提示选择。应该看起来像:

    BEGIN TRANSACTION  
      SELECT TOP 1 @id = siteid from siteids WITH (UPDLOCK, HOLDLOCK)
      DELETE siteids WHERE siteid = @id
    COMMIT TRANSACTION
    

    还要确保对siteid 列进行索引(或将其标记为主键,因为您说它是唯一的),否则它必须扫描表才能删除要删除的记录,这可能会使死锁变得更糟,因为它花费了更多的时间来删除。

    对于一般的死锁,运行 SQL 分析器并查看死锁图的样子 - 可能是其他情况。

    【讨论】:

    • 感谢您的回复。他是否会导致每天有大约 5000 万笔交易由多个线程每秒处理。不过我会试试的。
    • @vbNewbie 没有太多其他简单的选择。将其放置到位,添加 siteid 索引并查看其行为。如果仍然存在问题 - 请再次提供新的详细信息。使用整数而不是 nvvarchar siteid 可能更快,请参阅link
    • 我仍然遇到死锁,但只是添加了重试代码,我认为权衡是至少我的处理速度仍然比以前快。我想知道,既然我确实插入到同一个数据库中的表中,那也会对工作负载产生影响。
    • 您能否运行 SQL Server 配置文件并配置新跟踪来记录 Lock:DeadlockGraph 并重现问题?我认为死锁会影响性能。
    猜你喜欢
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 2021-12-25
    相关资源
    最近更新 更多