我必须更新表中的多个行数。 我的要求是,如果由于任何原因,更新结果返回0,那么应该回滚整个事务。 同时,如果发生任何异常,则必须回滚完整的事务。
简而言之,如果update语句返回0或者在更新表时发生了任何异常,我需要回滚整个更新事务。
这是我使用的代码。
CREATE TYPE [DBO].[EMPLOYEETYPETABLETYPE] AS TABLE
( EmployeeStatusKey INT, EmployeeStatusName VARCHAR(50) )
CREATE PROCEDURE [dbo].[usp_UpdateEmployeeStatusType]
@EmploymentStatusDetails [DBO].[EMPLOYEETYPETABLETYPE] READONLY
AS
BEGIN
SET NOCOUNT ON;
DECLARE @TransactionName varchar(20) = 'UpdateEmployeeStatus';
DECLARE @rowcount1 INT
BEGIN
BEGIN TRY
BEGIN TRANSACTION @TransactionName
UPDATE ES1
SET
ES1.EmployeeStatusName=ES2.EmployeeStatusName
FROM
[dbo].[EmployeeStatusTypes] ES1
INNER JOIN
@EmploymentStatusDetails ES2
ON
ES1.EmployeeStatusKey= ES2.EmployeeStatusKey
SET
@ROWCOUNT1=@@ROWCOUNT
IF @rowcount1 =0
GOTO PROBLEM
PROBLEM:
ROLLBACK TRAN @TransactionName
COMMIT
END TRY
BEGIN CATCH
SET @ROWCOUNT1=0
ROLLBACK TRAN @TransactionName
END CATCH
IF @rowcount1 =0
SELECT -178,@rowcount1;
ELSE
SELECT 178,@rowcount1;
END
END
我将数据表从C#代码传递给存储过程。 当我执行Sp时,没有抛出错误但是当我从C#代码中调用它时,我得到了异常
异常:ROLLBACK TRANSACTION请求没有相应的BEGIN TRANSACTION。
请提前帮助并表示感谢....
答案 0 :(得分:0)
删除那个糟糕的GOTO
TContext
并查看TRY-CATCH文档。您必须通过检查XACT_STATE()值来检查是否有任何要提交或回滚的事务。
答案 1 :(得分:0)
我用简化的脚本测试了你的脚本:
BEGIN TRY
print 'A:' + cast(@@trancount as varchar)
BEGIN TRANSACTION tranName
print 'B:' + cast(@@trancount as varchar)
GOTO PROBLEM -- you can comment this to simulate there is no error
PROBLEM:
begin
ROLLBACK TRAN tranName
print 'there is a problem'
end
print 'C:' + cast(@@trancount as varchar)
COMMIT
END TRY
BEGIN CATCH
print 'D:' + cast(@@trancount as varchar)
ROLLBACK TRAN tranName
END CATCH
出现问题时,输出就像
A:0
B:1
there is a problem
C:0
D:0
Msg 3903, Level 16, State 1, Line 18
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
如果我评论GOTO PROBLEM
所以没有问题,输出就像这样:
A:0
B:1
there is a problem
C:0
D:0
Msg 3903, Level 16, State 1, Line 18
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
你看到GOTO下的部分仍然在执行。
最后,COMMIT
仍然在没有可用事务的地方发生,因此COMMIT
抛出错误。这意味着您的脚本会抛出异常。
如果你摆脱GOTO,你会很好。无论如何,使用GOTO
是一种不好的做法。