Tengo un bloque de código que se ejecuta dentro de un TransactionScope y dentro de este bloque de código realizo varias llamadas al DB. Selecciona, actualiza, crea y elimina toda la gama. Cuando ejecuto mi eliminación, la ejecuto usando un método de extensión del SqlCommand que reenviará automáticamente la consulta si se bloquea, ya que esta consulta podría potencialmente llegar a un punto muerto.TransactionScope completado prematuramente
Creo que el problema ocurre cuando se golpea un interbloqueo y la función intenta volver a enviar la consulta. Este es el error que recibo:
La transacción asociada con la conexión actual se ha completado pero no se ha eliminado. La transacción debe eliminarse antes de que la conexión se pueda usar para ejecutar sentencias de SQL.
Este es el código simple que ejecuta la consulta (todo el código a continuación ejecuta dentro del uso de la TransactionScope):
using (sqlCommand.Connection = new SqlConnection(ConnectionStrings.App))
{
sqlCommand.Connection.Open();
sqlCommand.ExecuteNonQueryWithDeadlockHandling();
}
Aquí es el método de extensión que somete de nuevo la consulta de un punto muerto:
public static class SqlCommandExtender
{
private const int DEADLOCK_ERROR = 1205;
private const int MAXIMUM_DEADLOCK_RETRIES = 5;
private const int SLEEP_INCREMENT = 100;
public static void ExecuteNonQueryWithDeadlockHandling(this SqlCommand sqlCommand)
{
int count = 0;
SqlException deadlockException = null;
do
{
if (count > 0) Thread.Sleep(count * SLEEP_INCREMENT);
deadlockException = ExecuteNonQuery(sqlCommand);
count++;
}
while (deadlockException != null && count < MAXIMUM_DEADLOCK_RETRIES);
if (deadlockException != null) throw deadlockException;
}
private static SqlException ExecuteNonQuery(SqlCommand sqlCommand)
{
try
{
sqlCommand.ExecuteNonQuery();
}
catch (SqlException exception)
{
if (exception.Number == DEADLOCK_ERROR) return exception;
throw;
}
return null;
}
}
el error se produce en la línea:
sqlCommand.ExecuteNonQuery();
Gracias por la sugerencia sobre la supresión de transacciones en sentencias seleccionadas. Eso ayudó a resolver un problema de tiempo de espera que me estaba volviendo loco. –
Fantástica respuesta. Eso me estaba volviendo loco en una colección de colección de selección/inserción de instrucciones sql. Agregar la opción Suprimir resuelve el problema automáticamente. – IoChaos
¡Santa mierda, gracias! He estado luchando con esto todo el día. Una solución tan simple. – rossipedia