2017-03-10 267 views
1

代碼:此SqlTransaction已完成;它不再可用,爲什麼?

我試圖運行這個功能,但它拋出錯誤: 此的SqlTransaction已完成;它不再可用。

我已經使用其他方式,但不工作。我用它沒有USING但仍然是相同的錯誤。

爲什麼?

public Boolean AddWorkProgress(int WorkID, int ContractorID, float PhysicalProgress, 
    decimal FinancialProgress, int UserID, int OrgID, float FinancialProgressPecentage) 
{ 
    SqlCommand SqlCom = new SqlCommand("AddWorkProgress", DataBaseConnection.OpenConnection()); 
    SqlCom.CommandType = CommandType.StoredProcedure; 

    using (SqlTransaction sqlTrans = SqlCom.Connection.BeginTransaction()) 
    { 
     SqlCom.Transaction = sqlTrans; 

     try 
     { 
     SqlCom.Parameters.AddWithValue("@Work_ID", WorkID); 
     SqlCom.Parameters.AddWithValue("@Contractor_ID", ContractorID); 
     SqlCom.Parameters.AddWithValue("@PhysicalProgress", PhysicalProgress); 
     SqlCom.Parameters.AddWithValue("@FinancialProgress", FinancialProgress); 
     SqlCom.Parameters.AddWithValue("@OrgID", OrgID); 
     SqlCom.Parameters.AddWithValue("@fk_WebUsers_UserID", UserID); 
     SqlCom.Parameters.AddWithValue("@FinancialProgressPercentage", FinancialProgressPecentage); 
     SqlParameter SqlParamReturnStatus = new SqlParameter("@ReturnStatus", SqlDbType.Bit); 
     SqlCom.Parameters.Add(SqlParamReturnStatus); 
     SqlParamReturnStatus.Direction = ParameterDirection.Output; 
     SqlParameter SqlParamReturnStatusMessage = new SqlParameter("@ReturnStatusMessage", SqlDbType.VarChar, -1); 
     SqlCom.Parameters.Add(SqlParamReturnStatusMessage); 
     SqlParamReturnStatusMessage.Direction = ParameterDirection.Output; 
     SqlCom.ExecuteNonQuery(); 
     DataBaseConnection.CloseConnection(); 

     string ReturnStatusMessage = Convert.ToString(SqlParamReturnStatusMessage); 
     Boolean ReturnStatus = Convert.ToBoolean(SqlParamReturnStatus.Value); 
     // ProgressID = Convert.ToInt64(SqlParamReturnProgressID.Value); 

     sqlTrans.Commit(); 
     return ReturnStatus; 
     } 

     catch (Exception ex) 
     { 
     sqlTrans.Rollback(); 
     sqlTrans.Dispose(); 

     throw ex; 
     } 
    } 
} 
+0

看起來像你對我關閉連接您提交事務之前 –

+1

或許你也應該投入'使用您的連接'塊也是如此。 – David

+0

catch塊也是多餘的。 '使用'塊將回滾*和*處置交易。 –

回答

3

你commiting交易之前關閉連接:

MSDN
DataBaseConnection.CloseConnection(); 
// skipped code 
sqlTrans.Commit(); 

由於:

Both Commit and Rollback generates an InvalidOperationException if the connection is terminated or if the transaction has already been rolled back on the server.

這正是你的情況 - 連接會之前提交的交易/回滾關閉。

+0

我懷疑它會被調用。如果在這種情況下會回滾,將會更有意義。 – Evk

+0

@Evk我同意,這是不正確的措辭。我修改了答案以消除可能的誤導。 –

+0

如果您編寫關閉連接回滾所有以connection.BeginTransaction開始的掛起事務,會更加清晰 – Evk

0

如果連接已關閉,則無法回滾或提交事務。當連接關閉時,SQL Server無論如何都會回滾所有打開的事務。

catch塊也是多餘的。除非調用Commit(),否則事務在處置時會回滾。

最後,以不安全的方式處理連接。如果在CloseConnection()之前發生任何錯誤,連接將保持打開狀態。

使用以正確的方式連接和交易簡化了代碼很多:

var SqlCom = new SqlCommand("AddWorkProgress"); 
SqlCom.CommandType = CommandType.StoredProcedure; 
//... prepare the command. No need to use a connection 

using(var connection=DataBaseConnection.OpenConnection()) 
using(var transaction= connection.BeginTransaction()) 
{ 
    SqlCom.Connection=connection; 
    SqlCom.Transaction=transaction; 

    SqlCom.ExecuteNonQuery(); 
    transaction.Commit(); 

    //Process the results 
} 

就是這樣。當using塊完成時,連接將關閉。如果Commit()未被調用,則該事務將被回滾,只有在發生錯誤時纔會發生。

一旦將存儲過程的構造與其執行分開,可以進一步簡化代碼。例如,當類或應用程序初始化時,您只能創建一次該命令。要執行它每一次,你只要設置連接和參數值,例如:

public Boolean AddWorkProgress(int WorkID, int ContractorID, float PhysicalProgress, decimal FinancialProgress, int UserID, int OrgID, float FinancialProgressPecentage) 
{ 
    using(var connection=DataBaseConnection.OpenConnection()) 
    using(var transaction= connection.BeginTransaction()) 
    { 
     _addProgressCmd.Parameters["@Work_ID"].Value=WorkID; 
     .... 
     _addProgressCmd.Connection=connection; 
     _addProgressCmd.Transaction=transaction; 

     _addProgressCmd.ExecuteNonQuery(); 
     transaction.Commit(); 

     var status=(bool)_addProgressCmd.Parameters["@ReturnStatus"].Value; 
     var statusMsg=(string)_addProgressCmd.Parameters["@ReturnStatusMessage"].Value; 

     //Process the results 
     ... 
    } 
} 
相關問題