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

时间:2014-07-17 16:26:12

标签: c# sql-server ado.net transactionscope

我有一组存储过程(每个都是自己的事务)我需要作为事务运行。我使用Transaction Scope对象作为一个全有或全无的任务。在第一个ExecuteNonQuery运行之后我得到了SQLException" EXECUTE之后的事务计数表示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

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

1 个答案:

答案 0 :(得分:0)

您的存储过程中缺少BEGIN TRANSACTION