Rak*_*aur 17 sql-server ado.net t-sql transaction c#
我们真的需要 C# 中的事务处理以及双方的数据库存储过程吗?
C#:
Using(transaction with transaction scope)
{
Execute stored proc;
Transaction. Complete;
}
Run Code Online (Sandbox Code Playgroud)
SQL存储过程:
Create process
As
Begin try
Begin transaction
Commit
End try
Begin catch
Rollback
End catch
Run Code Online (Sandbox Code Playgroud)
Sol*_*zky 25
首先,您应该始终在所有过程中进行适当的事务处理,以便它们是由应用程序代码、另一个过程、在临时查询中单独调用、由 SQL 代理作业或其他方式调用都无关紧要. 但是单个 DML 语句或不进行任何修改的代码不需要显式事务。所以,我推荐的是:
在执行 2 个或多个 DML 语句时,您需要使用以下内容(如果希望保持一致,也可以对单个 DML 操作执行此操作):
CREATE PROCEDURE [SchemaName].[ProcedureName]
(
@Param DataType
...
)
AS
SET NOCOUNT ON;
DECLARE @InNestedTransaction BIT;
BEGIN TRY
IF (@@TRANCOUNT = 0)
BEGIN
SET @InNestedTransaction = 0;
BEGIN TRAN; -- only start a transaction if not already in one
END;
ELSE
BEGIN
SET @InNestedTransaction = 1;
END;
-- { 2 or more DML statements (i.e. INSERT / UPDATE / DELETE) }
IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
BEGIN
COMMIT;
END;
END TRY
BEGIN CATCH
IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
BEGIN
ROLLBACK;
END;
DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE(),
@ErrorState INT = ERROR_STATE(),
@ErrorSeverity INT = ERROR_SEVERITY();
-- optionally concatenate ERROR_NUMBER() and/or ERROR_LINE() into @ErrorMessage
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
RETURN;
END CATCH;
Run Code Online (Sandbox Code Playgroud)
当仅执行 1 个 DML 语句或仅执行 SELECT 时,您可以只执行以下操作:
CREATE PROCEDURE [SchemaName].[ProcedureName]
(
@Param DataType
...
)
AS
SET NOCOUNT ON;
BEGIN TRY
-- { 0 or 1 DML statements (i.e. INSERT / UPDATE / DELETE) }
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE(),
@ErrorState INT = ERROR_STATE(),
@ErrorSeverity INT = ERROR_SEVERITY();
-- optionally concatenate ERROR_NUMBER() and/or ERROR_LINE() into @ErrorMessage
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
RETURN;
END CATCH;
Run Code Online (Sandbox Code Playgroud)
其次,只有当您需要执行 1 个以上的查询/存储过程并且它们都需要分组为一个原子操作时,才应该在应用层处理事务。做单SqlCommand.Execute___只需要在 try / catch 中,而不是在 Transaction 中。
但是,当只进行一次调用时,在应用层执行事务会不会有什么坏处?如果它需要 MSDTC(Microsoft 分布式事务协调器),那么在没有明确需要的情况下,在应用层执行此操作对系统来说有点重。就个人而言,除非绝对必要,否则我更喜欢避免基于应用程序层的事务,因为它减少了孤立事务的可能性(如果在执行提交或回滚之前应用程序代码出现问题)。我还发现它有时会使调试某些情况更加困难。但话虽如此,我认为在制作单个proc时也在应用层处理事务在技术上没有任何问题称呼; 同样,单个 DML 语句是它自己的事务,不需要任何层的任何显式事务处理。
| 归档时间: |
|
| 查看次数: |
9994 次 |
| 最近记录: |