联结表上的SQL Server死锁

时间:2019-01-21 09:36:35

标签: sql-server deadlock

我遇到一个联结表上的死锁,而一个进程删除了某些条目,而另一个进程选择了另一个条目(在SQL Server 2014中)。

模式如下:

CREATE TABLE Junction
(
    JunctionId BIGINT IDENTITY(1,1) PRIMARY KEY,
    Table1Id INT NOT NULL,
    Table2Id INT NOT NULL,
    FOREIGN KEY (Table1Id) REFERENCES Table1(Table1Id),
    FOREIGN KEY (Table2Id) REFERENCES Table2(Table2Id) 
)

CREATE TABLE Table1
(
    Table1Id INT IDENTITY(1,1) PRIMARY KEY,
    SomeData1 VARCHAR(30) NOT NULL
)

CREATE TABLE Table2
(
    Table2Id INT IDENTITY(1,1) PRIMARY KEY,
    SomeData2 VARCHAR(30) NOT NULL
)

死锁图看起来像这样:

deadlock graph

死锁图xml:

<deadlock-list>
 <deadlock victim="process18679f088">
  <process-list>
   <process id="process18679f088" taskpriority="0" logused="0"             
        waitresource="PAGE: 6:1:19957 " waittime="4855" ownerId="5887063"
        transactionname="SELECT" lasttranstarted="2019-01-19T18:12:40.450" 
        XDES="0x1ba3aba20" lockMode="S" schedulerid="4" kpid="11756" 
        status="suspended" spid="63" sbid="0" ecid="0" priority="0"     
        trancount="0" lastbatchstarted="2019-01-19T18:12:40.450" 
        lastbatchcompleted="2019-01-19T18:12:40.453" lastattention="1900-01-
        01T00:00:00.453" clientapp=".Net SqlClient Data Provider"     
        hostname="WIN-*****" hostpid="96380" loginname="WIN-
        J***" isolationlevel="read committed (2)" 
        xactid="5887063" currentdb="6" lockTimeout="4294967295"         
        clientoption1="671088672" clientoption2="128056">
    <executionStack>
     <frame procname="GetSmth" 
            line="5" stmtstart="132" stmtend="1010" 
            sqlhandle="0x03000600ea777e2c037f2301bea9000001.....">
       SELECT t2.Table2Id, SomeData2 FROM Table2 t2 
       INNER JOIN Junction j ON t2.Table2Id=j.Table2Id
       WHERE Table1Id=@table1Id     
      </frame>
    </executionStack>
    <inputbuf> Proc [Database Id = 6 Object Id = 746485738]</inputbuf>
   </process>
   <process id="process1867be108" taskpriority="0" logused="363700" 
            waitresource="PAGE: 6:1:19956 " waittime="4021" 
            ownerId="5887012" transactionname="user_transaction" 
            lasttranstarted="2019-01-19T18:12:40.030" XDES="0x1c7aae700" 
            lockMode="X" schedulerid="2" kpid="85928" status="suspended" 
            spid="61" sbid="0" ecid="0" priority="0" trancount="2"     
            lastbatchstarted="2019-01-19T18:12:41.283" 
            lastbatchcompleted="2019-01-19T18:12:41.283" 
            lastattention="2019-01-19T18:12:40.413" clientapp=".Net 
            SqlClient Data Provider" hostname="WIN-****" 
            hostpid="96380" loginname="WIN-JFE5*****" 
            isolationlevel="read uncommitted (1)" xactid="5887012" 
            currentdb="6" lockTimeout="4294967295" clientoption1="671088672" 
            clientoption2="128056">
    <executionStack>
     <frame procname="RemoveSmth" 
                    line="6" stmtstart="188" stmtend="386"     
                    sqlhandle="0x03000600aef2cc644996e400c1a5000001.....">
            DELETE FROM Junction
            WHERE Table1Id=@table1Id AND Table2Id=@table2Id                  
     </frame>
    </executionStack>
    <inputbuf> Proc [Database Id = 6 Object Id = 1691153070]    </inputbuf>
   </process>
  </process-list>
  <resource-list>
   <pagelock fileid="1" pageid="19957" dbid="6" subresource="FULL" 
             objectname="Junction" 
             id="lock1af48eb80" mode="X" 
             associatedObjectId="72057594040614912">
    <owner-list>
     <owner id="process1867be108" mode="X"/>
    </owner-list>
    <waiter-list>
     <waiter id="process18679f088" mode="S" requestType="wait"/>
    </waiter-list>
   </pagelock>
   <pagelock fileid="1" pageid="19956" dbid="6" subresource="FULL" 
             objectname="Junction" 
             id="lock1af490200" mode="U" 
             associatedObjectId="72057594040614912">
    <owner-list>
     <owner id="process18679f088" mode="S"/>
    </owner-list>
    <waiter-list>
     <waiter id="process1867be108" mode="X" requestType="convert"/>
    </waiter-list>
   </pagelock>
  </resource-list>
 </deadlock>
</deadlock-list>

我是否正确理解死锁是由于进程的页面阻塞顺序不同而导致的?正如我从here中所读到的,一种可能的解决方案是将索引添加到Junction表FK字段中(这对吗?)。还有我不知道的另一种解决方案吗?

0 个答案:

没有答案