2011-09-05 6 views
7

Estoy usando .NET Framework 4.0, C# y SQL Server 2008 R2 en Windows Server 2008 R2. El contexto de datos de mi LINQ to SQL está en una biblioteca separada y el código en cuestión se está ejecutando en un servicio de Windows.¿Existe algún error o limitación en LINQ to SQL que provoque que se agote el tiempo de espera de los procedimientos almacenados?

Tengo un procedimiento almacenado de misión crítica bien probado que requiere unos 19 parámetros (sé que lo sé), realiza una lógica simple "si" y crea algunas variables, e inserta datos en 3 tablas. No utiliza cursores ni tablas temporales. He descrito lo que hace el SP, ya que no estoy en libertad de publicar el código sql.

Estoy viendo muchas publicaciones en Internet sobre SqlException debido al tiempo de espera del comando, y las respuestas rara vez van más allá de "aumentar el tiempo de espera del comando". Example

Estaba recibiendo la excepción antes mencionada, así que intenté aumentar el tiempo de espera del comando al crear el contexto de datos en 10 minutos. Todavía recibo la excepción después de que se haya sentado allí esperando esos 10 minutos. Luego agregué un registro de depuración para capturar el resultado de LINQ a SQL y ejecuté el SP en el estudio de SQL Server Management con los mismos valores de parámetro. Se completó con éxito en una fracción de de un segundo.

Aquí está la LINQ a SQL salida del registro (con tiempos de espera de volver a por defecto) mezclado con alguna otra salida del registro, he ofuscado el nombre de SP en este post:

16:01:37 15269 Irrelevant log line, deleted for StackOverflow 
EXEC @RETURN_VALUE = [dbo].[NAMEHIDDENONSTACKOVERFLOW] @Eastings = @p0, @Northings = @p1, @Speed = @p2, @UpdateDate = @p3, @UserId = @p4, @Postion = @p5, @Direction = @p6, @VehicleId = @p7, @Status = @p8, @Confidence = @p9, @Latitude = @p10, @Longitude = @p11, @PosLatitude = @p12, @PosLongitude = @p13, @WatchBoxId = @p14, @LastWatchBoxId = @p15, @WatchBoxIdAlert = @p16, @ImbolizationState = @p17, @TowAwayAlertState = @p18 
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [560120] 
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [5754714] 
-- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p3: Input DateTime (Size = -1; Prec = 0; Scale = 0) [02/08/2011 20:45:08] 
-- @p4: Input Int (Size = -1; Prec = 0; Scale = 0) [11] 
-- @p5: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Swindon United Kingdom] 
-- @p6: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [5] 
-- @p7: Input Int (Size = -1; Prec = 0; Scale = 0) [15269] 
-- @p8: Input Int (Size = -1; Prec = 0; Scale = 0) [901] 
-- @p9: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p10: Input Float (Size = -1; Prec = 0; Scale = 0) [51.939899] 
-- @p11: Input Float (Size = -1; Prec = 0; Scale = 0) [-2.125414] 
-- @p12: Input Float (Size = -1; Prec = 0; Scale = 0) [51.9333333] 
-- @p13: Input Float (Size = -1; Prec = 0; Scale = 0) [-2.1] 
-- @p14: Input Int (Size = -1; Prec = 0; Scale = 0) [-1] 
-- @p15: Input Int (Size = -1; Prec = 0; Scale = 0) [-1] 
-- @p16: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p17: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p18: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @RETURN_VALUE: Output Int (Size = -1; Prec = 0; Scale = 0) [Null] 
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1 

16:02:23 0 Error in DoPoll 1 Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 

La única pista que estoy Al salir de la búsqueda Stack Overflow es posible que haya un problema con algo llamado "parámetro sniffing", pero aún estoy leyendo sobre eso para averiguar de qué se trata.

Esto es realmente algo crítico y me costará un montón si falla en la producción, por lo que estoy tentado de retrotraer el LINQ y volver al ADO de vanilla. Mi pregunta es: ¿Hay algo de malo en mi enfoque (dicho de otra manera: ¿estoy siendo un idiota?) O ¿hay algún problema o error en LINQ to SQL que pueda estar causando este problema? ¿Hay algo que pueda hacer para solucionar este problema o sería mejor revertir a ADO vainilla?

+1

Algunas cosas para probar, si se trata de descubrimiento de parámetros: http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/ y http: //stackoverflow.com/questions/6986607/a-5sec-sp-hitting-a-30sec-timeout-through-linq-to-sql/6986902#6986902 –

+0

http://stackoverflow.com/questions/211355/parameter- sniffing-or-spoofing-in-sql-server es bastante bueno también. –

+1

+1 para "Sé que sé" :) – AakashM

Respuesta

0

Volví a la ADO de vanila y recibía la misma excepción, por lo que la respuesta debe ser "no, no es un error de LINQ to SQL". También refactoré el SP por los artículos para olfatear los parámetros y no ayudó. A medida que el código comenzó a funcionar nuevamente, solo puedo imaginar que esto fue un problema temporal del sistema o una falla de la base de datos. Para el beneficio de otros que tienen problemas similares y encontrar esta pregunta mediante búsqueda más adelante, actualizaré más si encuentro algo más, ya que un colega probará el código en otro sistema en breve.

EDITAR: Era un problema del sistema; específicamente, mi disco VMWare necesitaba desfragmentación.

(por consejo sobre meta, debo publicar mi propia respuesta en lugar de actualizar la pregunta).

+0

¿Tiene alguna cláusula 'IF' en SQL SP? A veces he notado informes SQL 1 conjunto de resultados, y algunas veces más. Trataré de encontrar el código que utilicé para determinar esto. – leppie

+0

Intenta ejecutar 'exec sys.sp_procedure_params_rowset 'yoursp'' varias veces y comprueba si el resultado sigue siendo el mismo. – leppie

+0

Sí, hay algunas cláusulas IF. –

0

LINQ-to-SQL utiliza vainilla ADO.NET bajo las sábanas. Al menos en lo que respecta a ADO.NET y SQL Server, no está cerca de maximizar la cantidad de parámetros que puede manejar. LINQ-to-SQL es muy amigable con el procedimiento almacenado, siempre que el proceso almacenado no esté haciendo algo tan horrible como crear SQL dinámico dentro del proceso o devolver resultados de tablas temporales.

¿Cómo está creando su asignación de Linq a SQL para el proceso almacenado? Hay una herramienta de comando de línea en SDK de Visual Studio llamada "SQLMETAL" que crea .dbml y .cs y, si se especifica mediante un cambio de línea de comando, también mapeará los procedimientos almacenados. Hace un análisis suficiente de los procedimientos almacenados para verificar que LINQ to SQL los manejará, y le dará mensajes de error para los procesos almacenados que no cumplen con sus estándares. Intente ejecutar SQLMETAL y vea qué tipo de mensajes recibe.

+0

Gracias Cylon. Soy consciente de que el ADO vainilla se usa bajo las sábanas (de hecho, la excepción que veo es una excepción ADO), pero no sabía que SqlMetal ofrece resultados útiles, así que lo intentaré. Para responder a su pregunta, genero el archivo dbml arrastrando y soltando el procedimiento almacenado desde el explorador del servidor hasta el diagrama de contexto de datos en Visual Studio 2010. –

+0

Siempre he encontrado que SqlMetal es una herramienta mejor que la función de arrastrar y soltar soltar la herramienta visual (que considero como demostración, no como calidad de producción).Linq-to-SQL tiene ciertas restricciones para los procedimientos almacenados, y sé que SqlMetal los verifica. –

+0

Probé eso, solo una advertencia de un objeto db no relacionado. –

1

Voy a hacer la suposición de que usted ha tratado de aumentar el tiempo de espera en el contexto de datos que LINQ, como usted ha mencionado que la mayoría de los mensajes que has encontrado sugirió que.

Sin embargo ...

lo que los viajes a mucha gente en casos como este es el servidor web, sobre todo si su funcionamiento en este IIS7.

He tenido casos en el pasado en los que he pasado innumerables horas persiguiendo cosas para saber dónde está pasando el tiempo, solo para solucionarlo en cinco segundos cambiando los valores de tiempo de espera para la aplicación del servidor en IIS7 panel de gestión.

No estoy diciendo que este sea definitivamente su problema, pero si solo tiene el servidor web configurado en 30 segundos (que es el predeterminado) puede sentarse y cambiar el tiempo de espera en su contexto de datos durante todo el día, y Nunca llegaré a ningún lado.

Si desea probar esto, inicie sesión en la máquina en la que se está ejecutando el servidor web, expanda el servidor/sitio web en el panel izquierdo para acceder a la aplicación desde donde se ejecuta el proceso almacenado.

En este punto se tienen pocos lugares para buscar. Si vuelve al nivel de sitio web EG: "Sitio web predeterminado" y hace clic en eso, luego haga clic en configuración avanzada a la extrema derecha y amplíe los límites de conexión, puede establecer el número de segundos para todo el sitio web allí.

Si llama a su SP desde un archivo ASP clásico, haga clic en su aplicación web y haga doble clic en el icono ASP en el panel central, expanda "Propiedades de límites" y cambie el valor de tiempo de espera del script.

Por último, si su hacer esto utilizando algún tipo de operación CGI, haga clic en la aplicación web a continuación, haga doble clic en CGI, y cambiar el tiempo de espera en ese país.

Por último, pero no menos importante, si ninguno de la ayuda anterior, se podría tratar de añadir el siguiente fragmento de XML a su archivo web.config aplicaciones en el lugar adecuado, para controlar el tiempo de ejecución del script .NET a cabo:

<system.web> 
     <httpRuntime executionTimeout="180"/> 
    <\system.web> 

Si no se está ejecutando en IIS7, tendrá que buscar en el panel de control que su servidor utiliza para configuraciones similares.

+0

Gracias por la respuesta detallada shawty pero desafortunadamente IIS no es parte de esta ecuación. Es un servicio de Windows. –

Cuestiones relacionadas