我正在尝试用事务编写一个sproc。有人可以告诉我下面的代码是否有任何问题,或者它是否能按预期工作?
ALTER procedure [dbo].[DeleteMetricMeter]
(
@SectionID int,
@MetricMeterID int,
@Result bit output
)
as
declare @MetricMeterCount int
declare @err int
declare @rowcount int
set xact_abort on
begin tran
select @MetricMeterCount = count(*) from luMetricMeters
where fkSectionID = @SectionID
select @err = @@error, @rowcount = @@rowcount
if (@err <> 0) or (@rowcount = 0)
begin
goto on_error
end
delete from luMetricMeterList
where pkMetricMeterID = @MetricMeterID
select @err = @@error, @rowcount = @@rowcount
if (@err <> 0) or (@rowcount = 0)
begin
goto on_error
end
delete from luMetricMeters
where pkMetricMeterID = @MetricMeterID
select @err = @@error, @rowcount = @@rowcount
if (@err <> 0) or (@rowcount = 0)
begin
goto on_error
end
if (@MetricMeterCount = 1)
begin
delete from luMetricSections
where pkSectionID = @SectionID
select @err = @@error, @rowcount = @@rowcount
if (@err <> 0) or (@rowcount = 0)
begin
goto on_error
end
end
commit tran
set @result = 1
return @result
on_error:
rollback tran
set @result = 0
return @result
答案 0 :(得分:1)
如果您使用的是Sql Server 2005+,我建议您使用TRY...CATCH (Transact-SQL),并查看[ B]部分。在交易中使用TRY ... CATCH ]
这将 GREATLY 简化您的程序。
答案 1 :(得分:0)
该程序存在一些问题:
您的代码不是线程安全的。应将MetricMeterCount查询更改为此选项,以防止其他线程在您的select和amp;之间执行删除操作。执行删除:
select @MetricMeterCount = count(*)
from luMetricMeters with (xlock, serializable)
where fkSectionID = @SectionID
我会写这样的代码:
ALTER procedure [dbo].[DeleteMetricMeter]
(
@SectionID int,
@MetricMeterID int,
@Result bit output
)
as
DECLARE @MetricMeterCount int
DECLARE @err int
DECLARE @rowcount int
SET xact_abort ON
BEGIN TRAN
DELETE FROM luMetricMeterList
WHERE pkMetricMeterID = @MetricMeterID
SELECT @err = @@error
IF (@err <> 0)
GOTO on_error
DELETE FROM luMetricMeters
WHERE pkMetricMeterID = @MetricMeterID
SELECT @err = @@error
IF (@err <> 0)
GOTO on_error
IF EXISTS (SELECT *
FROM luMetricMeters WITH (xlock, serializable)
WHERE fkSectionID = @SectionID)
BEGIN
DELETE FROM luMetricSections
WHERE pkSectionID = @SectionID
SELECT @err = @@error
IF (@err <> 0)
GOTO on_error
END
COMMIT TRAN
RETURN (0)
on_error:
ROLLBACK TRAN
RETURN (-1)
GO
注意:成功时返回值应为0,失败时返回负值。