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
funziona perfettamente, grazie! – Jay
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
Era piuttosto buono. Buone pratiche chiudendo il lettore a volte è un errore comune. – Robert