代码之家  ›  专栏  ›  技术社区  ›  diadem

SQL 2008 SP-死锁原因还是转移话题?

  •  0
  • diadem  · 技术社区  · 14 年前

    我的一个同事有一个存储过程,它执行以下操作
    开始转弯
    1)动态生成select语句。
    2)插入表X
    3)执行select语句
    终端转盘

    如果此存储过程由两个分隔线程同时运行,则会出现以下错误: System.Data.SqlClient.SqlException:事务(进程ID 57)在与另一个进程的锁通信缓冲区资源上死锁,已被选为死锁牺牲品。重新运行事务

    这个存储过程真的是问题所在吗?在我天真的头脑中,这看起来更糟的是一个种族状况,而不是僵局。

    2 回复  |  直到 14 年前
        1
  •  1
  •   Remus Rusanu    14 年前

    两个“先写后读”序列可以定义为死锁。您在文章中省略了一些“细节”,比如死锁发生在什么资源上以及涉及到哪些请求。我们会坐在自己的座位上,在字里行间阅读,从这样一篇没有充分记录的文章中,我们可以得出很多结论:

    1. 交叉读写。线程1插入键为A的行,然后选择键为B的行。线程2插入键为B的行,然后选择键为A的行。执行顺序为T1(A)、T2(B)、T1(B)-等待、T2(A)-死锁。
    2. 独立写入读取:T1插入A然后读取A,T2插入B然后读取B。关键信息: 键上没有索引,因此需要tabel扫描来读取a和/或b . 执行顺序是T1写A,T2写B,T1读A,开始扫描,T2的X锁块在B,T2读B,开始扫描,T1的X锁块在A,死锁。
    3. 独立的 优化 写读。对于大多数新手来说,这种情况最糟糕,因为适当的访问索引已经到位,但仍然会出现死锁。我把这个案子呈交给 Read/Write deadlock ,由于索引访问顺序不同,更新可能会死锁。不太可能是你的情况,但由于文件如此糟糕,任何事情都有可能发生。

    更多的死锁场景是可能的,但是我们将进入深奥或开始推断相当远的丢失信息在操作。

    如果我敢猜测,最有可能的情况是2)。案例1)可能很容易成为标识符。案例2)在简单的代码分析中比较难发现,因为它依赖于物理模式设计(索引结构)。

        2
  •  0
  •   KM.    14 年前

    在探查器中运行跟踪(选择空白模板),选择死锁图事件,并在出现的新标签(事件提取设置)上,将每个(单独保存检查死锁XML事件)保存在自己的文件中。在XML查看器中打开这个文件,就很容易知道发生了什么。每个进程都包含一堆过程调用等,所有锁也都在其中,因此您可以确定是什么导致了死锁。

    让这个跟踪一直运行到死锁再次发生,只有死锁发生时才会记录信息,所以不会有太多开销。