First on a stored procedure
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
Generating a serial number in accordance with the stored procedure.
Table Structure:
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 ' self-energizing a next sequence value ' , @ level0type = N ' SCHEMA ' , @ level0name = N ' the dbo ' , @ level1type = N ' TABLE ' , @ level1name = N ' cfg_increase ' , @ level2type = N ' the COLUMN ' , @ level2name = N ' NEXTVAL ' the GO EXECsys.sp_addextendedproperty the @name = N ' MS_Description ' , @value = N ' own key increment sequence ' , @ level0type = N ' SCHEMA ' , @ level0name = N ' the dbo ' , @ level1type = N ' TABLE ' , @ level1name = N ' cfg_increase ' the GO
no key column index, based on a script nextValue key table updates.
We crawled under high concurrency deadlock
<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="tengda2019718.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="tengda2019718.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="tengda2019718.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="tengda2019718.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>
To grab another deadlock:
<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="tengda2019718.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="tengda2019718.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="tengda2019718.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="tengda2019718.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="tengda2019718.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="tengda2019718.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>
Analysis: failed because no key column index, clustered index update is required to update the id, leading to an update request update locks, causing deadlock,
Solution:
Remove the clustered index id columns, build clustered index on a key, key update by updating the table to solve the problem. . . .