2016-04-11 1 views
10

fondL'opération de transaction ne peut être effectuée car il y a des demandes en attente de travail

J'ai un code qui ouvre une connexion SQL, commence une transaction et effectue certaines opérations sur la base de données. Ce code crée un objet à partir du DB (dequeue), récupère des valeurs et le sauvegarde. Toute l'opération doit avoir lieu dans une transaction. Tout le code fonctionne parfaitement sans la transaction.

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

code méthode 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; 
    } 
} 

Obtenir le code Path

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

Enregistrer le code

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

Le problème

Lorsque transaction.Commit() est appelée, je reçois l'erreur suivante:

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

Qu'est-ce que je fais mal?

EDIT: modifier pour vous dire que je les ai lu d'autres questions au sujet de ce problème sur le SO, mais n'a pas pu trouver liée à ADO.net

Répondre

14

J'ai eu ce problème avant et le problème a été le lecteur nécessaire à fermer. Essayez ceci:

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

fonctionne parfaitement, merci! – Jay

+1

De rien :). La chose est que nous pensons généralement que lorsque nous utilisons "using" le lecteur sera proche mais en utilisant les transactions il n'est pas fermé jusqu'à ce que vous appeliez la méthode Close(). – Ernest

+0

Était plutôt bien. Bonne pratique en fermant le lecteur parfois c'est une erreur commune. – Robert