2016-04-11 4 views
10

HintergrundDie Transaktion Operation kann nicht ausgeführt werden, weil dort anstehenden Anforderungen sind Arbeits

ich einen Code haben, die eine SQL-Verbindung öffnet, beginnt eine Transaktion und führt einige Operationen auf dem DB. Dieser Code erstellt ein Objekt aus dem DB (aus der Warteschlange), ruft einige Werte ab und speichert sie zurück. Die gesamte Operation muss in einer Transaktion stattfinden. Der ganze Code funktioniert perfekt ohne die Transaktion.

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

dequeue Methodencode

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

Get-Pfad-Code

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

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

Das Problem

Wenn transaction.commit() aufgerufen wird, bekomme ich folgende Fehlermeldung:

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

Was mache ich falsch?

EDIT: Schnell bearbeiten zu sagen, dass ich die anderen Fragen zu diesem Problem auf SO gelesen habe, kann aber nicht im Zusammenhang mit ADO.net finden

Antwort

14

Ich habe dieses Problem hatte vor und das Problem war der Leser benötigt geschlossen werden. Versuchen Sie dies:

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

funktioniert perfekt, danke! – Jay

+1

Gern geschehen :). Die Sache ist, dass wir normalerweise denken, dass wenn wir "using" benutzen, der Leser in der Nähe ist, aber Transaktionen benutzt, wird er nicht geschlossen, bis Sie die Methode Close() aufrufen. – Ernest

+0

War ziemlich gut. Gute Praxis Schließen Sie den Leser manchmal ist es ein häufiger Fehler. – Robert

Verwandte Themen