transaction - SQL Server, C#: excepción de tiempo de espera en la reversión de transacciones
transacciones sql (2)
Tengo un problema extraño. Tengo un programa .NET y mi lógica de proceso necesita una transacción de larga duración (~ 20min) en una base de datos de SQL Server 2005. Eso está bien, ya que nadie accede a la base de datos en paralelo. Cuando algo sale mal, la transacción debe ser revertida.
Con poca frecuencia y sin ningún patrón visible, la operación Rollback()
en mi objeto DbTransaction
lanza una SqlException
:
Message: "Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding." StackTrace: at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParserStateObject.ReadPacket(Int32 bytesExpected) at System.Data.SqlClient.TdsParserStateObject.ReadBuffer() at System.Data.SqlClient.TdsParserStateObject.ReadByte() at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest) at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest) at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest) at System.Data.SqlClient.SqlInternalTransaction.Rollback() at System.Data.SqlClient.SqlTransaction.Rollback()
No sé si es realmente un problema de tiempo de espera debido al hecho de que el código funciona a veces y otras no. Además, los únicos tiempos de espera que conozco son ConnectionTimeout
y CommandTimeout
, pero obviamente esos no son el problema en este caso.
¿Alguien tiene una idea sobre este problema?
Muchas gracias matias
Las transacciones pueden tardar un tiempo en retroceder; Si eso toma demasiado tiempo, seguro que obtendrás un tiempo de espera. Parece que no hay una manera obvia de influir en esto: puede intentar administrar la transacción a través de TSQL, luego puede (ab) usar CommandTimeout
, pero podría ser simplemente que toma un poco de tiempo si está haciendo muchas cosas. cambios dentro de la transacción; SQL Server asume que la mayoría de las cosas se ejecutarán hasta el final, por lo que "commit" es prácticamente gratis, mientras que "rollback" es más caro.
Matt Neerincx del equipo del servidor Sql abordó esto en una pregunta del foro de MSDN . Extraño pero cierto, el tiempo de espera de conexión de la cadena de conexión se utiliza para establecer el tiempo de espera. Verificado por él mirando el código fuente.