2016-04-11 28 views
10

tłoOperacja operacja nie może być wykonana, ponieważ istnieje oczekujące wnioski robocze

mam jakiś kod, który otwiera połączenie SQL rozpoczyna transakcję i wykonuje pewne operacje na DB. Ten kod tworzy obiekt z bazy danych (usuwanie danych), pobiera pewne wartości i zapisuje je z powrotem. Cała operacja musi mieć miejsce w transakcji. Cały kod działa doskonale bez transakcji.

using (var connection = new SqlConnection(connectionString)) 
{ 
    connection.Open(); 
    var transaction = connection.BeginTransaction(); 
    try 
    {      
     var myObject = foo.Dequeue(connection, transaction); 

     var url = myObj.GetFilePathUri(connection, transaction); 

     //some other code that sets object values 

     myObj.SaveMessage(connection, transaction); 
     transaction.Commit(); //error here 
    } 
    catch(Exception ex) 
    {      
     transaction.Rollback(); 
     //logging     
    } 
    finally 
    { 
     //cleanup code 
    } 
} 

kod metoda rozkolejkowania

public foo Dequeue(SqlConnection connection, SqlTransaction transaction) 
{ 
    using (var command = new SqlCommand(DEQUEUE_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     var reader = command.ExecuteReader(); 
     if (reader.HasRows) 
     { 
      reader.Read(); 
      ID = (Guid) reader["ID"]; 
      Name = reader["Name"].ToString(); 
      return this; 
     } 
     return null; 
    } 
} 

Pobierz kod Ścieżka

public string GetFilePathUri(SqlConnection connection, SqlTransaction transaction) 
{ 
    using (var command = new SqlCommand(FILEPATH_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     var reader = command.ExecuteReader(); 
     if (reader.HasRows) 
     { 
      reader.Read(); 
      return reader["Path"].ToString(); 
     } 
     return ""; 
    } 
} 

Zapisz Kod

public void SaveMessage(SqlConnection connection, SqlTransaction transaction) 
{ 
    using (var command = new SqlCommand(SAVE_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     command.Parameters.Add("@ID", SqlDbType.UniqueIdentifier).Value = ID; 
     command.Parameters.Add("@Name", SqlDbType.VarChar).Value = Name; 
     //other object params here 
     command.ExecuteNonQuery(); 
    } 
} 

Problem

Kiedy transaction.Commit() jest wywoływana, pojawia się następujący błąd:

The transaction operation cannot be performed because there are pending requests working on this transaction.

Co robię źle?

EDIT: Krótki edit powiedzieć Czytałem inne pytania dotyczące tego problemu na SO, ale nie mógł znaleźć żadnych związanych z ADO.NET

Odpowiedz

14

miałem ten problem przed i problem został czytelnikowi potrzebna zostać zamknięte. Spróbuj tego:

public foo Dequeue(SqlConnection connection, SqlTransaction transaction) 
{ 
    using (var command = new SqlCommand(DEQUEUE_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     var reader = command.ExecuteReader(); 
     if (reader.HasRows) 
     { 
      reader.Read(); 
      ID = (Guid) reader["ID"]; 
      Name = reader["Name"].ToString(); 
      reader.Close();//Closing the reader 
      return this; 
     } 
     return null; 
    } 
} 


public string GetFilePathUri(SqlConnection connection, SqlTransaction transaction) 
{ 
    string filePathUri = ""; 
    using (var command = new SqlCommand(FILEPATH_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     var reader = command.ExecuteReader(); 
     if (reader.HasRows) 
     { 
      reader.Read(); 
      filePathUri = reader["Path"].ToString(); 
     } 
     reader.Close();//Closing the reader 
    } 
    return filePathUri; 
} 
+0

działa idealnie, dzięki! – Jay

+1

Nie ma za co :). Chodzi o to, że zwykle myślimy, że kiedy używamy "używania", czytnik będzie blisko, ale używając transakcji, nie zostanie zamknięty, dopóki nie wywołasz metody Close(). – Ernest

+0

Był całkiem niezły. Dobra praktyka zamykania czytelnika czasami jest częstym błędem. – Robert