我是MS SQL Server的新手,我试图通过递增出现计数器(+1)来更新记录,如果数据丢失或我刚刚插入计数器值为零' 0'。
此外,我的应用程序以 parallel 运行,以处理数据数组a []的每个元素。并行处理数组时,SQL Server会为此引发死锁。虽然我设置了事务隔离级别,但是在表上发生了同样的死锁。我的应用程序是用Java / Camel / Hibernate编写的。
存储过程:
IF(@recordCount = 0 OR @recordCount > 1 )
BEGIN
IF(@chargeAbbreviation IS NOT NULL)
BEGIN
set transaction isolation level READ COMMITTED;
begin transaction;
UPDATE dbo.SLG_Charge_Abbreviation_Missing_Report WITH (UPDLOCK, HOLDLOCK)
SET dbo.SLG_Charge_Abbreviation_Missing_Report.Occurrence_Count+=1,dbo.SLG_Charge_Abbreviation_Missing_Report.ModifiedAt=GETDATE()
WHERE dbo.SLG_Charge_Abbreviation_Missing_Report.Jurisdiction_ID = @jurisdictionId AND
UPPER(dbo.SLG_Charge_Abbreviation_Missing_Report.Charge_Abbreviation) = @chargeAbbreviation AND
(UPPER(dbo.SLG_Charge_Abbreviation_Missing_Report.Statute_Code) = @statuteCode OR (dbo.SLG_Charge_Abbreviation_Missing_Report.Statute_Code IS NULL AND @statuteCode IS NULL)) AND
dbo.SLG_Charge_Abbreviation_Missing_Report.Product_Category_id = @productCategoryId
IF(@@ROWCOUNT = 0)
BEGIN
INSERT INTO dbo.SLG_Charge_Abbreviation_Missing_Report VALUES(@OriginalChargeAbbreviation,@jurisdictionId,@OriginalStatuteCode,@productCategoryId,GETDATE(),GETDATE(),1);
END
commit
END
SELECT TOP 0 * FROM dbo.SLG_Charge_Mapping
END
答案 0 :(得分:2)
您似乎正在尝试使用某些版本的Sam Saffron's upsert method。
要在使用holdlock
/ serializable
时利用Key-Range Locking,您需要有一个涵盖查询中列的索引。
如果您没有覆盖此查询的内容,可以考虑创建一个这样的内容:
create unique nonclustered index ux_slg_Charge_Abbreviation_Missing_Report_jid_pcid_ca_sc
on dbo.slg_Charge_Abbreviation_Missing_Report (
Jurisdiction_id
, Product_Category_id
, Charge_Abbreviation
, Statute_Code
);
我不认为这一行:set transaction isolation level read committed;
在这种情况下对你有所帮助。
set nocount on;
set xact_abort on;
if(@recordCount = 0 or @recordCount > 1 )
begin;
if @chargeAbbreviation is not null
begin;
begin tran;
update camr with (updlock, serializable)
set camr.Occurrence_Count = camr.Occurrence_Count + 1
, camr.ModifiedAt = getdate()
from dbo.slg_Charge_Abbreviation_Missing_Report as camr
where camr.Jurisdiction_id = @jurisdictionId
and camr.Product_Category_id = @productCategoryId
and upper(camr.Charge_Abbreviation) = @chargeAbbreviation
and (
upper(camr.Statute_Code) = @statuteCode
or (camr.Statute_Code is null and @statuteCode is null)
)
if @@rowcount = 0
begin;
insert into dbo.slg_Charge_Abbreviation_Missing_Report values
(@OriginalChargeAbbreviation,@jurisdictionId
,@OriginalStatuteCode,@productCategoryId
,getdate(),getdate(),1);
end;
commit tran
end;
select top 0 from dbo.slg_Charge_Mapping;
end;
注意:holdlock
与serializable
相同。
与上述解决方案相关的链接: