net maximo increase commandtimeout c# .net ado.net timeout

maximo - sqlcommand timeout c#



Excepción de tiempo de espera de conexión para una consulta con ADO.Net (16)

Como está utilizando ExecuteNonQuery, que no devuelve ninguna fila, puede probar este enfoque basado en el sondeo. Ejecuta la consulta de una manera asyc (sin devolución de llamada) pero la aplicación esperará (dentro de un ciclo while) hasta que se complete la consulta. De MSDN . Esto debería resolver el problema del tiempo de espera. Por favor pruébalo.

Pero estoy de acuerdo con los demás en que debería pensar más en optimizar la consulta para realizarla en menos de 30 segundos.

IAsyncResult result = command.BeginExecuteNonQuery(); int count = 0; while (!result.IsCompleted) { Console.WriteLine("Waiting ({0})", count++); System.Threading.Thread.Sleep(1000); } Console.WriteLine("Command complete. Affected {0} rows.", command.EndExecuteNonQuery(result));

Actualización : Parece que la consulta no arroja ningún tiempo de espera. La conexión se está agotando.

Este es un código de muestra para ejecutar una consulta. A veces, al ejecutar consultas que requieren mucho tiempo, arroja una excepción de tiempo de espera.

No puedo usar ninguna de estas técnicas: 1) Aumento del tiempo de espera. 2) Ejecútelo de forma asíncrona con una devolución de llamada. Esto necesita ejecutarse de manera síncrona.

por favor, sugiera cualquier otra tecnología para mantener viva la conexión mientras se ejecuta una consulta que consume tiempo.

private static void CreateCommand(string queryString, string connectionString) { using (SqlConnection connection = new SqlConnection( connectionString)) { SqlCommand command = new SqlCommand(queryString, connection); command.Connection.Open(); command.ExecuteNonQuery(); } }


Debería dividir su consulta en múltiples fragmentos que cada uno ejecuta dentro del período de tiempo de espera.


Primero debe verificar su consulta para ver si está optimizada y de alguna manera no se está ejecutando en los índices que faltan. Se asignan 30 segundos para la mayoría de las consultas , incluso en bases de datos grandes si están ajustadas correctamente. Si tiene una prueba sólida utilizando el plan de consulta de que la consulta no se puede ejecutar más rápido que eso, entonces debe aumentar el tiempo de espera, no hay otra manera de mantener la conexión, ese es el propósito del tiempo de espera para finalizar la conexión si el la consulta no se completa en ese marco de tiempo.


Recientemente tuvimos un problema similar en una base de datos SQL Server 2000.

Durante su consulta, ejecute esta consulta en su base de datos maestra en el servidor db y vea si hay bloqueos que debe solucionar:

select spid, db_name(sp.dbid) as DBname, blocked as BlockedBy, waittime as WaitInMs, lastwaittype, waitresource, cpu, physical_io, memusage, loginame, login_time, last_batch, hostname, sql_handle from sysprocesses sp where (waittype > 0 and spid > 49) or spid in (select blocked from sysprocesses where blocked > 0)

SQL Server Management Studio 2008 también contiene un monitor de actividad muy interesante que le permite ver el estado de su base de datos durante su consulta.

En nuestro caso, fue un bloqueo de red que mantuvo ocupada la base de datos. Fue algún código VB heredado que no desconectó su conjunto de resultados lo suficientemente rápido.


Si no puede aumentar el tiempo de espera, su única opción es reducir el tiempo de la consulta para ejecutar dentro del tiempo de espera predeterminado de 30 segundos.


Si tiene restricciones para usar el proceso predeterminado de cambiar el valor de tiempo de espera, lo más probable es que tenga que trabajar mucho más. Las siguientes opciones vienen a la mente

  1. Valide con su DBA y otra revisión de código que realmente ha optimizado la consulta lo mejor posible
  2. Trabaje en la estructura de base subyacente para ver si hay alguna ganancia que pueda obtener en el lado de la base de datos, creando / modificando una idex (es).
  3. Divídalo en varias partes, incluso si esto significa ejecutar procedimientos con múltiples parámetros de retorno que simplemente llamen a otro parámetro. (Esta opción no es elegante, y honestamente, si su código REALMENTE va a tomar tanto tiempo, yo iría a la administración y volvería a discutir el tiempo de espera de 30 segundos)

Tengo que estar de acuerdo con Terrapin.

Tiene algunas opciones sobre cómo bajar el tiempo. En primer lugar, si su empresa emplea DBA, recomendaría pedirles sugerencias.

Si esa no es una opción, o si quiere probar algunas otras cosas primero, aquí están sus tres principales opciones:

  1. Divida la consulta en componentes que se ejecutan bajo el tiempo de espera. Este es probablemente el más fácil.
  2. Cambie la consulta para optimizar la ruta de acceso a través de la base de datos (en general, acceda a un índice lo más cerca posible)
  3. Cambie o agregue índices para afectar la ruta de acceso de su consulta.

Tiendo a no me gusta aumentar el tiempo de espera de conexión / comando ya que en mi opinión eso sería una cuestión de cuidar el síntoma, no el problema


command.CommandTimeout *= 2;

Eso duplicará el tiempo de espera predeterminado, que es de 30 segundos.

O bien, ponga el valor de CommandTimeout en un archivo de configuración, para que pueda ajustarlo según sea necesario sin volver a compilar.


Si tiene prohibido usar las características de la API de acceso a datos para permitir que una consulta dure más de 30 segundos, entonces necesitamos ver el SQL.

Las ganancias de rendimiento que se lograrán mediante la optimización del uso de ADO.NET son pequeñas en comparación con las ganancias de optimizar el SQL.

Y ya estás usando el método más eficiente para ejecutar SQL. Otras técnicas serían increíblemente más lentas (aunque, si realizó una recuperación rápida de sus filas y un procesamiento realmente lento del lado del cliente usando DataSets, es posible que pueda obtener la recuperación inicial en menos de 30 segundos, pero lo dudo. )

Si supiéramos si estás haciendo inserciones, entonces tal vez deberías estar usando inserciones masivas. Pero no sabemos el contenido de su sql.


Este es un hack UGLY, pero puede ayudar a resolver su problema temporalmente hasta que pueda solucionar el problema real

private static void CreateCommand(string queryString,string connectionString) { int maxRetries = 3; int retries = 0; while(true) { try { using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand(queryString, connection); command.Connection.Open(); command.ExecuteNonQuery(); } break; } catch (SqlException se) { if (se.Message.IndexOf("Timeout", StringComparison.InvariantCultureIgnoreCase) == -1) throw; //not a timeout if (retries >= maxRetries) throw new Exception( String.Format("Timedout {0} Times", retries),se); //or break to throw no error retries++; } } }


Actualización: Parece que la consulta no arroja ningún tiempo de espera. La conexión se está agotando.

Iow, incluso si no ejecuta una consulta, ¿la conexión expira? porque hay dos tiempos de espera: conexión y consulta. Todo el mundo parece enfocarse en la consulta, pero si obtienes tiempos de espera de conexión, es un problema de red y no tiene nada que ver con la consulta: la conexión primero tiene que establecerse antes de que se ejecute una consulta, obviamente.


¿Ha intentado envolver su sql dentro de un procedimiento almacenado? Parece que tienen una mejor administración de la memoria. He visto tiempos de espera como este antes en el plan de instrucción sql con consultas internas utilizando ADO clásico. es decir, seleccione * de (seleccione ....) t unión interior somthingTable. Donde la consulta interna estaba devolviendo una gran cantidad de resultados.

Otros consejos 1. Realizar lecturas con la sugerencia de ejecución con (nolock), está sucio y no lo recomiendo, pero tenderá a ser más rápido. 2. También vea el plan de ejecución de sql que intenta ejecutar y reduzca el escaneo de filas, el orden en el que une las tablas. 3. mira agregar algunos índices a tus tablas para lecturas más rápidas. 4. También descubrí que eliminar filas es muy costoso, puedes intentar y limitar el número de filas por llamada. 5. Cambiar variables @table con # tablas temporales también me ha funcionado en el pasado. 6. También es posible que hayas guardado un plan de ejecución incorrecto (escuchado, nunca visto).

Espero que esto ayude


¿Has pensado en dividir la consulta en varios trozos más pequeños?

Además, ha ejecutado su consulta en el Asesor de ajuste de motor de base de datos en:

Management Studio> Herramientas> Asesor de ajuste de motor de base de datos

Por último, ¿podríamos echar un vistazo a la consulta en sí?

aclamaciones


Puede valer la pena intentar paginar los resultados.


simplemente establezca la propiedad CommandTimeout de sqlcommand en 0, esto hará que el comando espere hasta que finalice la consulta ... por ejemplo:

SqlCommand cmd = new SqlCommand(spName,conn); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandTimeout = 0;