SQL错误“在批处理结束时检测到不可提交的事务”,而db上没有事务

Gab*_*.Pe 5 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, @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
Run Code Online (Sandbox Code Playgroud)

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

问题是:如果我没有事务SQL端,而只有一个try-catch块,而所有事务处理都在代码上执行,那么SQL为什么谈论Uncommitable Transaction?

我已经在网上搜索过,发现了大量有关Uncommittable Transaction错误的资料,但实际上,在SQL端到处都有事务处理。

我希望我已经以一种可以理解的方式解释了这个问题。我显然可以提供任何进一步的信息。

非常感谢您的帮助!

干杯,加布里埃

M.A*_*Ali 0

将所有操作包装在事务内的 TRY BLOCK 中,并让 sql server 为您处理它,而不是您在应用程序中处理它。在 Try 块中显式 BEGIN 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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢您的回答,M.Ali!不幸的是,代码是企业应用程序的一部分,事务处理无法修改。我非常有兴趣了解为什么它会这样。例如,SQL事务引擎和C#事务引擎之间有交互吗?无论如何,非常感谢! (2认同)