我有一个存储过程,它正在更新SQL Server中的多个表。此过程正在使用C#代码。
如果我只在C#代码中应用交易,这是一个好习惯吗?
我是否需要在C#代码和存储过程中应用事务?
由于
答案 0 :(得分:6)
如果进程只在单个SqlCommand
中调用单个存储过程,那么只需处理存储过程内的事务,就不需要从C#代码管理它。您只需要在C#代码中对其进行管理,以便在多个SqlCommand
执行中维护事务。
仅供参考,只有满足以下两个条件时才需要在两个层中管理交易:
SqlCommand
调用在上述场景之外,管理两个层中的交易毫无意义,因为只有一个交易。如果事务是在C#代码中启动的,则调用BEGIN TRAN
时存储过程中发生的所有事情都会增加@@TRANCOUNT
。并且@@TRANCOUNT
通过发出COMMIT
中显示@@TRANCOUNT
的相同数量(在这种情况下,发出COMMIT
,ROLLBACK
返回到0之前,事务才会真正提交。在存储过程中再次在C#代码中,此时SQL Server实际上执行了真正的" commit")。但是,单个@@TRANCOUNT
会将COMMIT
带回0,无论它处于什么数字。如果在存储过程中发生这种情况,则无法在C#代码中发出ROLLBACK
或TRY / CATCH
,因为事务不再存在,因此您需要首先测试活动事务。
假设您至少使用SQL Server 2005,如果不是更新,请确保使用T-SQL COMMIT / ROLLBACK
语法来管理存储过程中的BEGIN TRY
BEGIN TRAN;
UPDATE Table1 ... ;
UPDATE Table2 ... ;
UPDATE Table3 ... ;
COMMIT TRAN;
END TRY
BEGIN CATCH
IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK TRAN;
END;
THROW; -- if using SQL Server 2012 or newer, else use RAISERROR
END CATCH;
。 即使您只是在C#代码中管理事务,也需要TRY / CATCH语法来正确捕获错误并退出proc。
例如:
{{1}}