我面临死锁
在另一个进程的锁资源上死锁了 被选为死锁受害者。
问题在SQL-Server中,我通过对特定列选择max id来在数据库中插入数据,然后添加一个增量,得到将插入记录的值。 我将程序称为下面提到的代码:
CREATE
PROCEDURE [dbo].[Web_GetMaxColumnID]
@Col_Name nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
DECLARE @MaxID BIGINT;
SET NOCOUNT ON;
-- Insert statements for procedure here
BEGIN
BEGIN TRAN
SET @MaxID = (
SELECT Col_Counter
FROM Maintenance_Counter WITH (XLOCK, ROWLOCK)
WHERE COL_NAME = @Col_Name
)
UPDATE Maintenance_Counter
SET Col_Counter = @MaxID + 1
WHERE COL_NAME = @Col_Name
COMMIT
END
SELECT (
CONVERT(
VARCHAR,
(
SELECT office_id
FROM Maintenance
)
) + '' + CONVERT(VARCHAR, (@MaxID))
) AS MaxID
END
任何人都帮帮我.....
答案 0 :(得分:1)
正如Marc已经回答的那样,请使用SEQUENCE。它可用于所有受支持的SQL Server版本,即2012及更高版本。避免它的唯一原因是针对像2008这样的不受支持的版本。
在这种情况下,您可以在更新计数器值的同一语句中设置计数器变量。这样,您就不需要任何交易或锁定,例如:
declare @counterValue bigint
UPDATE Maintenance_Counter
SET Col_Counter = Col_Counter + 1 , @counterValue=Col_Counter+1
WHERE COL_NAME = @Col_Name
select @counterValue
答案 1 :(得分:0)
Yo可以使用序列生成增量值,避免任何阻塞。
我已将自己的计数器生成器改编为您的直接替代品。它动态创建SQL语句来管理序列,如果序列不存在我们正在寻找的值,它就会创建它。
ALTER PROCEDURE [dbo].[Web_GetMaxColumnID]
@Col_Name nvarchar(50)
AS
declare @Value bigint;
declare @SQL nvarchar(64);
BEGIN
if not exists(select * from sys.objects where object_id = object_id(N'dbo.MY_SEQUENCES_' + @Col_Name) and type = 'SO')
begin
set @SQL = N'create sequence dbo.MY_SEQUENCES_' + @Col_Name + ' as bigint start with 1';
exec (@SQL);
end
set @SQL = N'set @Value = next value for dbo.MY_SEQUENCES_' + @Col_Name;
exec sp_executesql @SQL, N'@Value bigint out', @Value = @Value out;
select @Value ;
END
唯一的不便是你的价值观可能会产生差距(因为你可能已经检索了一个值,但最终没有使用它)。这对我的桌子来说不是问题,但你必须考虑它。