C# 事务计数与分层事务不匹配

C# 事务计数与分层事务不匹配,c#,sql-server,ado.net,transactionscope,C#,Sql Server,Ado.net,Transactionscope,我有一组存储过程,它们各自都是一个事务,我需要作为事务运行。我使用事务范围对象作为其全部或无任务。在第一个ExecuteOnQuery运行之后,我在EXECUTE之后获得SQLException事务计数,这表明BEGIN和COMMIT语句的数量不匹配。上一次计数=1,当前计数=0。运行过程而不将其包装在事务作用域中可以很好地工作,并且我没有遇到上面的错误,但是我需要确保所有过程都运行到完成时没有错误,或者所有过程都需要回滚 public static void ImportHedges(Data

我有一组存储过程,它们各自都是一个事务,我需要作为事务运行。我使用事务范围对象作为其全部或无任务。在第一个ExecuteOnQuery运行之后,我在EXECUTE之后获得SQLException事务计数,这表明BEGIN和COMMIT语句的数量不匹配。上一次计数=1,当前计数=0。运行过程而不将其包装在事务作用域中可以很好地工作,并且我没有遇到上面的错误,但是我需要确保所有过程都运行到完成时没有错误,或者所有过程都需要回滚

public static void ImportHedges(DataTable hedges, string fileName, string importedBy)
    {
        try
        {
            using (TransactionScope ts = new TransactionScope())
            {

                using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Energy"].ConnectionString))
                {
                    connection.Open();

                    SqlCommand newContractsCommand = new SqlCommand("SP_ImportNewContracts", connection);
                    newContractsCommand.CommandType = CommandType.StoredProcedure;
                    newContractsCommand.Parameters.Add("@ImportedBy", SqlDbType.NVarChar).Value = importedBy;
                    newContractsCommand.Parameters.Add("@FileName", SqlDbType.NVarChar).Value = fileName;

                    DataTable newContracts = hedges.AsEnumerable().Where(i => i["ContractStatus"].ToString() == "New").CopyToDataTable();
                    SqlParameter newContractsParameter = newContractsCommand.Parameters.AddWithValue("@Hedges", newContracts);
                    newContractsParameter.SqlDbType = SqlDbType.Structured;
                    newContractsParameter.TypeName = "dbo.Hedges";

                    SqlCommand renewContractsCommand = new SqlCommand("SP_ImportRenewContracts", connection);
                    renewContractsCommand.CommandType = CommandType.StoredProcedure;
                    renewContractsCommand.Parameters.Add("@ImportedBy", SqlDbType.NVarChar).Value = importedBy;
                    renewContractsCommand.Parameters.Add("@FileName", SqlDbType.NVarChar).Value = fileName;

                    DataTable renewContracts = hedges.AsEnumerable().Where(i => i["ContractStatus"].ToString() == "Renew").CopyToDataTable();
                    SqlParameter renewContractsParameter = newContractsCommand.Parameters.AddWithValue("@Hedges", renewContracts);
                    renewContractsParameter.SqlDbType = SqlDbType.Structured;
                    renewContractsParameter.TypeName = "dbo.Hedges";

                    SqlCommand amendContractsCommand = new SqlCommand("SP_ImportAmendContracts", connection);
                    amendContractsCommand.CommandType = CommandType.StoredProcedure;
                    amendContractsCommand.Parameters.Add("@ImportedBy", SqlDbType.NVarChar).Value = importedBy;
                    amendContractsCommand.Parameters.Add("@FileName", SqlDbType.NVarChar).Value = fileName;

                    DataTable amendContracts = hedges.AsEnumerable().Where(i => i["ContractStatus"].ToString() == "Amend").CopyToDataTable();
                    SqlParameter amendContractsParameter = newContractsCommand.Parameters.AddWithValue("@Hedges", amendContracts);
                    amendContractsParameter.SqlDbType = SqlDbType.Structured;
                    amendContractsParameter.TypeName = "dbo.Hedges";

                    SqlCommand fixedContractsCommand = new SqlCommand("SP_ImportFixedContracts", connection);
                    fixedContractsCommand.CommandType = CommandType.StoredProcedure;
                    fixedContractsCommand.Parameters.Add("@ImportedBy", SqlDbType.NVarChar).Value = importedBy;
                    fixedContractsCommand.Parameters.Add("@FileName", SqlDbType.NVarChar).Value = fileName;

                    DataTable fixedContracts = hedges.AsEnumerable().Where(i => i["ContractStatus"].ToString() == "Fixed").CopyToDataTable();
                    SqlParameter fixedContractsParameter = newContractsCommand.Parameters.AddWithValue("@Hedges", fixedContracts);
                    fixedContractsParameter.SqlDbType = SqlDbType.Structured;
                    fixedContractsParameter.TypeName = "dbo.Hedges";

                    newContractsCommand.ExecuteNonQuery();
                    renewContractsCommand.ExecuteNonQuery();
                    amendContractsCommand.ExecuteNonQuery();
                    fixedContractsCommand.ExecuteNonQuery();

                    connection.Close();
                }

                ts.Complete();
            }
        }

        catch (Exception Ex)
        {
            Email.SendEmail("Error in: Energy at " + DateTime.Now.ToString() + " - " + Thread.CurrentPrincipal.Identity.Name, Ex.Message + Environment.NewLine + Ex.StackTrace);
        }


    }





ALTER PROCEDURE [dbo].[SP_ImportNewContracts]
@FileName       NVARCHAR(100),
@ImportedBy     NVARCHAR(20),
@Hedges         dbo.Hedges READONLY
AS

BEGIN TRY

INSERT INTO ClientRetailers (ClientID, RetailerID, StartDate, EndDate, EnergyType,        ContractStatus)
SELECT DISTINCT (SELECT ClientID FROM Clients WHERE CustomerNumber = H.CustomerNumber),(SELECT RetailerID FROM Retailers WHERE RetailerName = H.Retailer),
RetailerStartDate, RetailerEndDate, EnergyType, ContractStatus
FROM @Hedges H
WHERE NOT EXISTS (SELECT ClientRetailersID FROM ClientRetailers WHERE ClientID = (SELECT ClientID FROM Clients WHERE CustomerNumber = H.CustomerNumber) AND
RetailerID = (SELECT RetailerID FROM Retailers WHERE RetailerName = H.Retailer) AND EnergyType = H.EnergyType) 

INSERT INTO ClientRetailerProducts (ClientRetailersID, ProductID, StartDate, EndDate,     ProductPercentage)
SELECT DISTINCT (SELECT TOP(1) ClientRetailersID FROM ClientRetailers WHERE ClientID =     (SELECT TOP(1) ClientID FROM Clients WHERE CustomerNumber = H.CustomerNumber) AND
RetailerID = (SELECT TOP(1) RetailerID FROM Retailers WHERE RetailerName = H.Retailer)     AND EnergyType = H.EnergyType),
(SELECT ProductID FROM Products WHERE ProductName = H.HedgeType), ProductStartDate,     ProductEndDate, ProductPercentage
FROM @Hedges H
WHERE NOT EXISTS (SELECT TOP(1) ClientRetailersID FROM ClientRetailerProducts WHERE     ProductID = (SELECT TOP(1) ProductID FROM Products WHERE ProductName = H.HedgeType)
AND ClientRetailersID = (SELECT TOP(1) ClientRetailersID FROM ClientRetailers WHERE     ClientID = (SELECT TOP(1) ClientID FROM Clients WHERE CustomerNumber = H.CustomerNumber)     AND
RetailerID = (SELECT TOP(1) RetailerID FROM Retailers WHERE RetailerName = H.Retailer)     AND EnergyType = H.EnergyType))

INSERT INTO Files (FileName, ImportDate, ImportedBy)
VALUES (@FileName, GETDATE(), @ImportedBy)


DECLARE @FileID INT = SCOPE_IDENTITY()

INSERT INTO Hedge (ClientRetailersID, ProductID, FixedPricePerUnit, Year, January, February, March, April,
                May, June, July, August, September, October, November, December, FileID)
SELECT  (SELECT TOP(1) ClientRetailersID FROM ClientRetailers WHERE ClientID = (SELECT TOP(1) ClientID FROM Clients WHERE CustomerNumber = H.CustomerNumber) AND
        RetailerID = (SELECT TOP(1) RetailerID FROM Retailers WHERE RetailerName = H.Retailer) AND EnergyType = H.EnergyType), 
    (SELECT TOP(1) ProductID FROM Products WHERE ProductName = H.HedgeType), FixedPricePerUnit, Year, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec, @FileID
FROM @Hedges H


COMMIT TRANSACTION

END TRY

BEGIN CATCH

IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION

END CATCH

其他三个存储过程遵循相同的事务结构。

存储过程中缺少BEGIN事务。

不能有子事务。。。sql server中的sorrynested事务是一个神话。文档中确实讨论了它们,但它们并没有做您认为应该做的事情。如果您开始第二个事务,唯一实际发生的事情就是它增加了@trancount。任何回滚操作都将回滚事务并将@trancount重置为0.Darn。好的,我想我必须将这些过程变成一个巨大的过程/事务。您使用命名事务、未命名事务还是两者的组合?两者混合会导致问题。。。