我有一个悲观并发的应用程序锁,并在Asp.Net Mvc中生成代码。
using (var scope = new TransactionScope())
{
using (var context = new Context())
{
var submitedEntity = context.Entities.Add(entity);
context.SaveChanges();
context.Entry(submitedEntity).Reload();
code = submitedEntity.Code;
scope.Complete();
}
}
在SQL Server Trigger中生成代码
Create Trigger [dbo].[OnInsertEntity]
On [dbo].[TableName]
After Insert
As
Begin
Begin Transaction
Declare @ID BigInt,
@LastCode Int,
@Length Int,
@Code nChar(5)
Select @ID = ID
From Inserted
Select @LastCode = Max(Convert(Int, Code))
From [TableName]
With (TABLOCKX, HOLDLOCK)
If @@RowCount = 0
Set @LastCode = 0
Waitfor Delay '00:00:05'
Select @Length = Max_Length
From Sys.Columns
Where Name = N'Code' And
[Object_ID] = Object_ID('[TableName]')
Select @LastCode = @LastCode + 1,
@Code = Replicate('0', @Length - Len(@LastCode)) + Convert(nChar, @LastCode)
Update [TableName]
Set Code = @Code
Where ID = @ID
Commit Transaction
End
错误:
catch (DbUpdateException ex)
事务(进程ID)在锁定资源上与另一个进行了死锁 进程并被选为死锁受害者。重新运行该交易。
有什么问题?
感谢。
答案 0 :(得分:0)
如果我正确理解您的代码,您似乎只是尝试将正在运行的数字更新到每一行,而它实际上是一个包含前导零的nchar字段。
在整个桌子上使用带独占锁定的触发器等听起来不错。我宁愿建议你在表格中使用标识字段。如果你真的需要一个前导零,我只需要在表中添加一个计算列,该列使用编号的标识字段。