Ho un'applicazione C# che manipola i dati in una tabella all'interno di un database SQL Server utilizzando le transazioni. Il codice è molto semplice e in fondo è questa:La tabella del database rimane bloccata, se il processo client viene interrotto dopo l'inizio della transazione
public string ConnectionString;
public OleDbConnection DbConnection;
public OleDbTransaction DbTransaction;
// ... some initialization stuff ...
DbTransaction = DbConnection.BeginTransaction();
try
{
// ... some insert/update/delete here ...
DbTransaction.Commit();
}
catch (Exception e)
{
// ...
DbTransaction.Rollback();
}
Ora, una situazione stato segnalato da un cliente, che la tabella/set di righe è rimasto bloccato, mentre non vi era alcuna istanza dell'applicazione attiva in esecuzione. La sua prima ipotesi è stata che si è verificato un errore durante la transazione e che non ci sia alcun blocco try-catch-block con un rollback (ma questo non è assolutamente il caso, dal momento che c'è una corretta gestione degli errori). Posso riprodurre la situazione, se si imposta un punto di interruzione nel debugger prima di DbTransaction.Commit();
e quindi si elimina il processo dal Task Manager di Windows. Quindi la transazione rimane aperta (posso vederlo in esecuzione DBCC OPENTRAN
) e rimane un blocco, che impedisce di lavorare ulteriormente con una nuova istanza dell'applicazione.
La mia domanda: come posso gestire in sicurezza una situazione come questa: il processo viene ucciso dopo l'avvio della transazione e non ha alcuna possibilità di eseguire il commit/rollback della transazione? Per quanto ne so, non riesco a riconoscere, se l'applicazione viene uccisa dal Task Manager (scheda "Processo"). Quindi posso in qualche modo abortire automaticamente la transazione (ad esempio dopo un certo timeout) o cos'altro posso fare? Per favore aiuto.
davvero una correzione, ma si può fare questo con meno di un blocco di tabella? Puoi prendere transazioni più piccole? – Paparazzi