2016-04-11 20 views
10

sfondoL'operazione di transazione non può essere eseguita perché non ci sono richieste in sospeso di lavoro

Ho qualche codice che apre una connessione SQL, inizia una transazione ed esegue alcune operazioni sul DB. Questo codice crea un oggetto dal DB (dequeue), ottiene alcuni valori e lo salva. L'intera operazione deve essere eseguita in una transazione. Tutto il codice funziona perfettamente senza la transazione.

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 
    } 
} 

codice del metodo dequeue

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; 
    } 
} 

ottenere il codice Percorso

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 ""; 
    } 
} 

Salva codice

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(); 
    } 
} 

Il problema

Quando transaction.Commit() viene chiamata, ottengo il seguente errore:

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

Che cosa sto facendo di sbagliato?

EDIT: Quick Edit dire Ho letto le altre domande su questo problema su SO, ma non ho trovato alcun correlate a ADO.net

risposta

14

Ho avuto questo problema prima e il problema è stato il lettore necessaria essere chiuso. Prova questo:

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

funziona perfettamente, grazie! – Jay

+1

Prego :). Il fatto è che di solito pensiamo che quando usiamo "using" il lettore sarà vicino ma usando le transazioni non è chiuso finché non chiamate il metodo Close(). – Ernest

+0

Era piuttosto buono. Buone pratiche chiudendo il lettore a volte è un errore comune. – Robert

Problemi correlati