我有一个存储过程,该存储过程是使用事务从C#代码中调用的。
当我在C#(其控制台应用程序)中运行代码时,不是从catch块获取结果,而是引发异常:



C#代码:

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace app1
{
    class Program
    {
        static void Main(string[] args)
        {
            string res = "";
            string resDesc = "";

            res = WriteToDB(1,out resDesc);

            Console.WriteLine(res);
            Console.WriteLine(resDesc);


            Console.Read();
        }

        public static string WriteToDB(int val, out string resultDesc)
        {
            resultDesc = "";
            string result = "";
            string connectionString = ConfigurationManager.ConnectionStrings["SqlAppConnection"].ConnectionString;
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                SqlTransaction transaction = connection.BeginTransaction("transcation1");
                try
                {
                    using (SqlCommand cmd = new SqlCommand())
                    {
                        cmd.Connection = transaction.Connection;
                        cmd.Transaction = transaction;
                        cmd.CommandText = "usp_Test_Proc";
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@check", val);
                        SqlParameter res = cmd.Parameters.Add("@result", SqlDbType.Int);
                        res.Direction = ParameterDirection.Output;
                        SqlParameter resDesc = cmd.Parameters.Add("@resultDesc", SqlDbType.VarChar, 100);
                        resDesc.Direction = ParameterDirection.Output;
                        cmd.ExecuteNonQuery();
                        result = res.Value.ToString().Trim();
                        resultDesc = resDesc.Value.ToString();
                        transaction.Commit();
                    }
                }
                catch (Exception ex)
                {
                    result = "Exception";
                    resultDesc = ex.Message;
                    transaction.Rollback();
                }
            }
            return result;
        }

    }
}

存储过程:
ALTER PROCEDURE [dbo].[usp_Test_Proc] (
                                            @check        int,
                                            @result           INT output,
                                            @resultDesc       VARCHAR(100)
output)
AS
  BEGIN
      SET nocount ON;
      SET xact_abort ON;

      IF @check != 0
        BEGIN
            BEGIN try
                SET @result = 0;
                SET @resultDesc = 'aa';
                --RAISERROR('Error from raiserror',1,1)
                THROW 99001, 'Error from throw', 1;
            END try
            BEGIN catch
                SET @result = 1;
                SET @resultDesc = concat('catch block',ERROR_MESSAGE());
            END catch;
        END
        ELSE
        BEGIN
                SET @result = 0;
                SET @resultDesc = 'done';
                end
  END;

GO

当存储过程引发错误时,我没有进入catch块,而是得到了一个异常消息,说“在批处理结束时检测到不可提交的事务。该事务已回滚。”

但是,如果我在SSMS中运行存储过程,它将按预期工作:
c# - 在批处理结束时检测到不可提交的事务。交易回滚-LMLPHP

当我从C#代码调用结果时,为什么结果不同?

最佳答案

这是因为您将'set xact_abort on'设置为..按照documentation,xact_abort用于
指定当Transact-SQL语句引发运行时错误时,SQL Server是否自动回滚当前事务。

另外,您需要在throw中将“状态”值设置为-1,以使事务变得不可使用。

08-07 12:23
查看更多