Tsql 存储过程事务的第一次尝试
我正在尝试使用事务编写存储过程。有谁能告诉我下面的代码是否会有问题,或者它是否能按预期工作Tsql 存储过程事务的第一次尝试,tsql,Tsql,我正在尝试使用事务编写存储过程。有谁能告诉我下面的代码是否会有问题,或者它是否能按预期工作 ALTER procedure [dbo].[DeleteMetricMeter] ( @SectionID int, @MetricMeterID int, @Result bit output ) as declare @MetricMeterCount int declare @err int declare @rowcount int set xact_abort
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
如果您使用的是Sql Server 2005+,我建议您使用并查看[B.在事务中使用TRY…CATCH]
这将大大简化您的过程。如果您使用的是Sql Server 2005+,我建议您使用并查看[B.在事务中使用TRY…CATCH]
这将大大简化您的程序。该程序存在一些问题: 您不应该计算rowcount,除非它确实指示错误。如果没有删除数据,则无需回滚。 您的代码不是线程安全的。MetricMeterCount查询应更改为此,以防止其他线程在选择和执行删除之间执行删除:
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,失败的返回值应为负数。该过程存在一些问题: 您不应该计算rowcount,除非它确实指示错误。如果没有删除数据,则无需回滚。 您的代码不是线程安全的。MetricMeterCount查询应更改为此,以防止其他线程在选择和执行删除之间执行删除:
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,失败返回值应为负数。您使用的是哪个版本的SQL Server?您使用的是哪个版本的SQL Server?