簡體   English   中英

已經有與此命令關聯的打開的DataReader,沒有嵌套的datareader

[英]There is already an open DataReader associated with this Command, without nested datareaders

我間歇性地收到以下錯誤。 已經有一個與此命令相關聯的打開的DataReader,必須先關閉它。

我讀到,當同一連接中有嵌套的DataReader時,可能會發生這種情況,但就我而言,我正在使用以下代碼執行所有查詢。

    private SqlTransaction Transaction { get; set; }
    private SqlConnection Connection { get; set; }
    private DbRow Row {get; set;}

    public Row Exec(string sql){
        try{
            //Begin connection/transaction
            Connection = new SqlConnection(connectionString);
            Connection.Open();
            Transaction = Connection.BeginTransaction("SampleTransaction");  

            //create command
            SqlCommand command = new SqlCommand(sql, Connection);
            command.Transaction = Transaction;

            //execute reader and close it
            //HERE IS THE PROBLEM, THE READER ALWAYS READ UNTIL THE END
            //BEFORE ANOTHER CAN BE OPENED
            reader = command.ExecuteReader();                
            while (reader.Read())
            {
                object[] value = new object[reader.FieldCount];
                reader.GetValues(value);
                List<object> values = new List<object>(value);                    
                Rows.Add(values);
            }                
            reader.Close();
            Transaction.Commit();
            Connection.Dispose();
            Connection = null;
        }
        catch
        {
           Transaction.Rollback();
           Connection.Dispose();
           Connection = null;
        }
        finally
        {
            if (reader != null && !reader.IsClosed) reader.Close();
        }
    }

這樣,結果存儲在一個對象中,並且沒有嵌套的閱讀器。 我還讀到將'MultipleActiveResultSets = True'添加到連接字符串可以解決使用嵌套閱讀器時的問題。 此解決方案還能解決我的問題嗎? 由於錯誤是間歇性的,並且僅在生產環境中發生,因此我無法對其進行多次測試。

There is already an open DataReader associated with this Command which must be closed first. at 
          System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) at 

System.Data.SqlClient.SqlInternalTransaction.Rollback() at

System.Data.SqlClient.SqlTransaction.Rollback() at 

Application.Lib.DB.DBSQLServer.Rollback()
 at Application.Lib.DB.DBSQLServer.Execute(String sql, Dictionary`2 parameters, 

Nullable`1 timeout, Boolean useTransaction) at 

Application.UtilDB.Execute(String sql, Dictionary`2 parameters, Nullable`1 

timeout, Boolean useTransaction) in c:\Application\DBUtil.cs:line 37 at 

Application.A.CollectionFromDataBase(Int32 cenId, 

IDB db, Int32 includeId, Boolean allStatus) in c:\Application\Activities.cs:line 64 at

Application.ActivitiesController.CheckForConflictsBeforeSave(String aulId, String insId) in c:\Application\AlocController.cs:line 212

問題是,當查詢失敗時,由於數據讀取器已經打開以處理查詢,因此無法回滾事務。

拋出第二個異常,而第一個異常丟失。

我只是將回滾放置在try catch塊中,並使用AggregateException類拋出兩個異常。

try
{
    Transaction.Rollback();
    Connection.Dispose();
    Connection = null;
}
catch (Exception ex2)
{                                                      
    throw new AggregateException(new List<Exception>() { e, ex2 });
}

盡管無論如何都會回滾該事務,但我認為您也可以嘗試在回滾之前關閉數據讀取器,因此它可能會起作用。

if (reader != null && !reader.IsClosed) 
    reader.Close();
Transaction.Rollback();

由於這種情況僅發生在生產中,因此錯誤很可能在您附加的代碼之外。

防止這種情況的最常見方法是始終以以下方式進行編碼:

reader = command.ExecuteReader();
try
{
        for (int i = 0; i < reader.FieldCount; i++)
        {
            dbResult.Columns.Add(reader.GetName(i));
            dbResult.Types.Add(reader.GetDataTypeName(i));
        }
        while (reader.Read())
        {
            object[] value = new object[reader.FieldCount];
            reader.GetValues(value);
            List<object> values = new List<object>(value);                    
            Rows.Add(values);
        }                            
}
finally
{
    reader.Close();
}

注意finally塊,它確保無論如何都關閉讀者。 我印象深刻的是,您的代碼中發生了某些事情,使讀者無法打開,但該錯誤在您發布的代碼中不可見。

我建議您將其包含在上述try / finally塊中,您的錯誤很可能已得到解決

編輯,以澄清:這可能無法解決原始顯示的代碼范圍之外存在的任何錯誤,但是它將防止數據讀取器處於打開狀態。 我建議的finally塊不會阻止任何異常,它們會傳播到您在其外部使用的任何處理程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM