zoukankan      html  css  js  c++  java
  • 记录一次高并发下由索引引发的死锁问题

    先上一个存储过程

    CREATE PROCEDURE [dbo].[GetNextIncrease] 
    @key varchar(50),
    @next int output
    as
    begin
        begin try
             begin tran
                select @next=NextVal from cfg_increase with(xlock,rowlock)  where [Key]=@key;
                --if @next!=NULL
                    begin
                        update cfg_increase set NextVal=(NextVal+1) WHERE [Key]=@key;
                    end
                --else
                --    begin
                --        update btlh_dep_hdbh set hd=1 WHERE depid=@depid;
                --    end 
             commit
        end try
        begin catch
            rollback
        end catch
    end
    GO

    根据存储过程生成一个流水号。

    表结构:

    CREATE TABLE [dbo].[cfg_increase](
        [Id] [INT] IDENTITY(1,1) NOT NULL,
        [Key] [NVARCHAR](255) NOT NULL,
        [NextVal] [INT] NOT NULL,
     CONSTRAINT [PK__cfg_incr__3214EC07351DDF8C] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'自增序列标识' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cfg_increase', @level2type=N'COLUMN',@level2name=N'Key'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'自增序列下一个值' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cfg_increase', @level2type=N'COLUMN',@level2name=N'NextVal'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'自定义键自增序列' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cfg_increase'
    GO

    key列上无索引, 脚本根据key 更新表的nextValue。

    在高并发下抓取到的一个死锁

    <deadlock-list>
     <deadlock victim="process20ec00bc8">
      <process-list>
       <process id="process20ec00bc8" taskpriority="0" logused="16928" waitresource="KEY: 9:72057594111787008 (8194443284a0)" waittime="6494" ownerId="2653399770" 
       transactionname="user_transaction" lasttranstarted="2019-07-22T15:41:26.487" XDES="0xb0ec9790" lockMode="U" schedulerid="8" kpid="0" 
       status="suspended" spid="99" sbid="0" ecid="0" priority="0" trancount="3" lastbatchstarted="2019-07-22T15:41:26.500" 
       lastbatchcompleted="2019-07-22T15:41:26.500" clientapp=".Net SqlClient Data Provider" hostname="iZ5nf507j3o23hZ" hostpid="39352" 
       loginname="sa" isolationlevel="read committed (2)" xactid="2653399770" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
        <executionStack>
         <frame procname="td2019718.dbo.GetNextIncrease" line="11" stmtstart="474" stmtend="606" sqlhandle="0x030009007a829c477a1b57016faa00000100000000000000">
    update cfg_increase set NextVal=(NextVal+1) WHERE [Key]=@key;     </frame>
        </executionStack>
        <inputbuf>
    Proc [Database Id = 9 Object Id = 1201439354]    </inputbuf>
       </process>
       <process id="process9412988" taskpriority="0" logused="21428" waitresource="KEY: 9:72057594111787008 (a0c936a3c965)" waittime="6502" ownerId="2653399772" 
       transactionname="user_transaction" lasttranstarted="2019-07-22T15:41:26.487" XDES="0xe7e45620" lockMode="X" schedulerid="6" kpid="0" 
       status="suspended" spid="83" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2019-07-22T15:41:26.500" 
       lastbatchcompleted="2019-07-22T15:41:26.500" clientapp=".Net SqlClient Data Provider" hostname="iZ5nf507j3o23hZ" hostpid="39352" 
       loginname="sa" isolationlevel="read committed (2)" xactid="2653399772" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
        <executionStack>
         <frame procname="td2019718.dbo.GetNextIncrease" line="8" stmtstart="242" stmtend="448" sqlhandle="0x030009007a829c477a1b57016faa00000100000000000000">
    select @next=NextVal from cfg_increase with(xlock,rowlock)  where [Key]=@key;
                --if @next!=NULL     </frame>
        </executionStack>
        <inputbuf>
    Proc [Database Id = 9 Object Id = 1201439354]    </inputbuf>
       </process>
      </process-list>
      <resource-list>
       <keylock hobtid="72057594111787008" dbid="9" objectname="td2019718.dbo.cfg_increase" indexname="PK__cfg_incr__3214EC07351DDF8C" id="lock10fc9ea00" mode="X" associatedObjectId="72057594111787008">
        <owner-list>
         <owner id="process9412988" mode="X"/>
        </owner-list>
        <waiter-list>
         <waiter id="process20ec00bc8" mode="U" requestType="wait"/>
        </waiter-list>
       </keylock>
       <keylock hobtid="72057594111787008" dbid="9" objectname="td2019718.dbo.cfg_increase" indexname="PK__cfg_incr__3214EC07351DDF8C" id="lock12e75a280" mode="X" associatedObjectId="72057594111787008">
        <owner-list>
         <owner id="process20ec00bc8" mode="X"/>
        </owner-list>
        <waiter-list>
         <waiter id="process9412988" mode="X" requestType="wait"/>
        </waiter-list>
       </keylock>
      </resource-list>
     </deadlock>
    </deadlock-list>

    抓取到的另外一个死锁:

    <deadlock-list>
     <deadlock victim="processba954c8">
      <process-list>
       <process id="processba954c8" taskpriority="0" logused="16384" waitresource="KEY: 9:72057594111787008 (8194443284a0)" waittime="1495" ownerId="2653399801" transactionname="user_transaction" lasttranstarted="2019-07-22T15:41:26.490" XDES="0x30e6833c0" lockMode="X" schedulerid="11" kpid="0" status="suspended" spid="91" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2019-07-22T15:41:26.507" lastbatchcompleted="2019-07-22T15:41:26.507" clientapp=".Net SqlClient Data Provider" hostname="iZ5nf507j3o23hZ" hostpid="39352" loginname="sa" isolationlevel="read committed (2)" xactid="2653399801" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
        <executionStack>
         <frame procname="td2019718.dbo.GetNextIncrease" line="8" stmtstart="242" stmtend="448" sqlhandle="0x030009007a829c477a1b57016faa00000100000000000000">
    select @next=NextVal from cfg_increase with(xlock,rowlock)  where [Key]=@key;
                --if @next!=NULL     </frame>
        </executionStack>
        <inputbuf>
    Proc [Database Id = 9 Object Id = 1201439354]    </inputbuf>
       </process>
       <process id="process20ec00bc8" taskpriority="0" logused="16928" waitresource="KEY: 9:72057594111787008 (8194443284a0)" waittime="1493" ownerId="2653399770" transactionname="user_transaction" lasttranstarted="2019-07-22T15:41:26.487" XDES="0xb0ec9790" lockMode="U" schedulerid="8" kpid="0" status="suspended" spid="99" sbid="0" ecid="0" priority="0" trancount="3" lastbatchstarted="2019-07-22T15:41:26.500" lastbatchcompleted="2019-07-22T15:41:26.500" clientapp=".Net SqlClient Data Provider" hostname="iZ5nf507j3o23hZ" hostpid="39352" loginname="sa" isolationlevel="read committed (2)" xactid="2653399770" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
        <executionStack>
         <frame procname="td2019718.dbo.GetNextIncrease" line="11" stmtstart="474" stmtend="606" sqlhandle="0x030009007a829c477a1b57016faa00000100000000000000">
    update cfg_increase set NextVal=(NextVal+1) WHERE [Key]=@key;     </frame>
        </executionStack>
        <inputbuf>
    Proc [Database Id = 9 Object Id = 1201439354]    </inputbuf>
       </process>
       <process id="process9412988" taskpriority="0" logused="21428" waitresource="KEY: 9:72057594111787008 (a0c936a3c965)" waittime="1501" ownerId="2653399772" transactionname="user_transaction" lasttranstarted="2019-07-22T15:41:26.487" XDES="0xe7e45620" lockMode="X" schedulerid="6" kpid="0" status="suspended" spid="83" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2019-07-22T15:41:26.500" lastbatchcompleted="2019-07-22T15:41:26.500" clientapp=".Net SqlClient Data Provider" hostname="iZ5nf507j3o23hZ" hostpid="39352" loginname="sa" isolationlevel="read committed (2)" xactid="2653399772" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
        <executionStack>
         <frame procname="td2019718.dbo.GetNextIncrease" line="8" stmtstart="242" stmtend="448" sqlhandle="0x030009007a829c477a1b57016faa00000100000000000000">
    select @next=NextVal from cfg_increase with(xlock,rowlock)  where [Key]=@key;
                --if @next!=NULL     </frame>
        </executionStack>
        <inputbuf>
    Proc [Database Id = 9 Object Id = 1201439354]    </inputbuf>
       </process>
      </process-list>
      <resource-list>
       <keylock hobtid="72057594111787008" dbid="9" objectname="td2019718.dbo.cfg_increase" indexname="PK__cfg_incr__3214EC07351DDF8C" id="lock10fc9ea00" mode="X" associatedObjectId="72057594111787008">
        <owner-list>
         <owner id="process9412988" mode="X"/>
        </owner-list>
        <waiter-list>
         <waiter id="processba954c8" mode="X" requestType="wait"/>
        </waiter-list>
       </keylock>
       <keylock hobtid="72057594111787008" dbid="9" objectname="td2019718.dbo.cfg_increase" indexname="PK__cfg_incr__3214EC07351DDF8C" id="lock10fc9ea00" mode="X" associatedObjectId="72057594111787008">
        <owner-list/>
        <waiter-list>
         <waiter id="process20ec00bc8" mode="U" requestType="wait"/>
        </waiter-list>
       </keylock>
       <keylock hobtid="72057594111787008" dbid="9" objectname="td2019718.dbo.cfg_increase" indexname="PK__cfg_incr__3214EC07351DDF8C" id="lock12e75a280" mode="X" associatedObjectId="72057594111787008">
        <owner-list>
         <owner id="process20ec00bc8" mode="X"/>
        </owner-list>
        <waiter-list>
         <waiter id="process9412988" mode="X" requestType="wait"/>
        </waiter-list>
       </keylock>
      </resource-list>
     </deadlock>
    </deadlock-list>

    分析:因为key列无索引,更新需要使用id聚集索引去更新,导致更新请求更新锁时失败,引发死锁问题,

    解决办法:

    去除id列的聚集索引 ,在key 上建立聚集索引,更新通过key 更新表,解决问题。。。。

  • 相关阅读:
    Verilog非阻塞赋值的仿真/综合问题 (Nonblocking Assignments in Verilog Synthesis)上
    异步FIFO结构及FPGA设计 跨时钟域设计
    FPGA管脚分配需要考虑的因素
    An Introduction to Delta Sigma Converters (DeltaSigma转换器 上篇)
    An Introduction to Delta Sigma Converters (DeltaSigma转换器 下篇)
    中国通信简史 (下)
    谈谈德国大学的电子专业
    中国通信简史 (上)
    Verilog学习笔记
    Verilog非阻塞赋值的仿真/综合问题(Nonblocking Assignments in Verilog Synthesis) 下
  • 原文地址:https://www.cnblogs.com/niceletter/p/11227256.html
Copyright © 2011-2022 走看看