C# SQL错误“;在批处理结束时检测到未提交的事务;在db上没有事务

C# SQL错误“;在批处理结束时检测到未提交的事务;在db上没有事务,c#,sql,sql-server,transactions,C#,Sql,Sql Server,Transactions,在我的代码的不同点上,我面临以下问题。 调用存储过程后,从DB(SQL Server)返回SqlException,并显示消息“在批处理结束时检测到不可模仿的事务。事务回滚”。存储过程结构如下所示: USE [EXAMPLE_DB] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[sp_ExampleStoredProcedure] @Parameter INT, @AnotherParame

在我的代码的不同点上,我面临以下问题。 调用存储过程后,从DB(SQL Server)返回SqlException,并显示消息“在批处理结束时检测到不可模仿的事务。事务回滚”。存储过程结构如下所示:

USE [EXAMPLE_DB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_ExampleStoredProcedure]
@Parameter INT, @AnotherParameter INT

AS
BEGIN
    BEGIN TRY

    SET NOCOUNT ON;


    DECLARE @Variable INT;
    DECLARE @AnotherVariable CHAR;
    DECLARE @ErrMsg VARCHAR;

    SET @ErrMsg = '';

    /*Doing Some Stuff Here (Select, IF-THEN, etc...)

            /* I call another stored procedure */   
            EXECUTE [dbo].[sp_SecondStoredProcedure] 
                       @Param = 'Blabla'
                      ,@Param2 = 'BlaBlaBla'


            /*Here I handle some custom output parameters from second stored                           
                     procedure to handle errors */



                    /* Other stuff here */

END TRY

BEGIN CATCH    
        SET @CustomExitCode = 'XXXXX';
        SET @ErrMsg = (SELECT ERROR_MESSAGE()); 
END CATCH;

END
正如您所看到的,在存储过程中没有事务处理。 我使用TransactionScope类处理事务代码端(C#),调用事务范围内的各种存储过程,包括上面的一个(失败的一个)

问题是:如果我没有事务SQL端,只有一个try-catch块,所有事务处理都在代码上执行,那么为什么SQL会谈论不可模仿的事务

我已经在网上搜索了很多关于不可提交事务错误的资料,但实际上,SQL端到处都有事务处理

我希望我已经以可以理解的方式解释了这个问题。 很明显,我可以得到任何进一步的信息

非常感谢你的帮助

干杯,
Gabriele

将事务中TRY块中的所有操作打包,让sql server为您处理,而不是在应用程序中处理。在Try块中显式开始TRAN和COMMIT Trans,如果在此事务期间出现任何错误,则回滚它

我会做一些像

ALTER PROCEDURE [dbo].[sp_ExampleStoredProcedure]
@Parameter INT, @AnotherParameter INT
AS
BEGIN
    SET NOCOUNT ON;
 BEGIN TRY
    DECLARE @Variable INT;
    DECLARE @AnotherVariable CHAR;
    DECLARE @ErrMsg VARCHAR;

    SET @ErrMsg = '';
BEGIN TRANSACTION;      --<-- Begin here 

    /*Doing Some Stuff Here (Select, IF-THEN, etc...)*/

            /* I call another stored procedure */   
            EXECUTE [dbo].[sp_SecondStoredProcedure] 
                       @Param = 'Blabla'
                      ,@Param2 = 'BlaBlaBla'
            /*Here I handle some custom output parameters from second stored                           
                     procedure to handle errors */

                    /* Other stuff here */
COMMIT TRANSACTION;     --<-- Commit here if nothing gone wrong

END TRY

BEGIN CATCH    
  IF (@@TRANCOUNT > 0)
   BEGIN
      ROLLBACK TRANSACTION;   --<-- Rollback if something went wrong
   END

           /*Other error logging here*/
        SELECT @CustomExitCode = 'XXXXX', @ErrMsg = ERROR_MESSAGE(); 
END CATCH;

END
ALTER过程[dbo]。[sp_示例存储过程]
@参数INT,@AnotherParameter INT
作为
开始
不计数;
开始尝试
声明@Variable INT;
声明@AnotherVariable CHAR;
声明@ErrMsg VARCHAR;
设置@ErrMsg='';

开始交易-- 如果在“代码”中启动事务,则该事务也将对过程可见。否则,它将如何成为真正的交易

当您将事务与try-catch和error结合使用时,许多错误(特别是在使用XACT_-ABORT-ON时)将导致“不可提交的事务错误”,请参阅XACT_状态文档

出现错误时,必须对事务执行某些操作,如果不执行,则在离开过程时事务会自动回滚


由于这些和其他原因,我们通常避免将try-catch与事务一起使用。由于您使用的是C#代码,您最好将try-catch移动到应用程序部分,并将事务处理与XACT#U ABORT一起保留,这意味着它将在出现错误时回滚

谢谢您的回答M.Ali!不幸的是,代码是企业应用程序的一部分,不能修改事务处理。我很想了解它为什么会这样。例如,SQL事务引擎和C#事务引擎之间的任何交互?无论如何,非常感谢你!如果有多个表要处理,那么最好在所有表都正确更新/插入之后,应用程序执行提交。(IMHO!)显示您的c#呼叫代码。。。。