2010-03-10 15 views
5

estoy recibiendo un error de tiempo de espera al intentar ejecutar una consulta LINQ (-to-SQL)Depuración de una dura LINQ a SQL Tiempo de espera

System.Data.SqlClient.SqlException: Tiempo de espera agotado. El período de tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde.

Ahora bien, esto es no sólo un caso de una consulta lenta:

  • corro el equivalente SQL en SQL Server Management Studio y se completa rápidamente (2 segundos)
  • estoy estableciendo mi CommandTimeout en 2 minutos.
  • Cuando ejecuto la misma consulta en una prueba unitaria, se completa de manera exitosa y rápida. Es decir: solo recibo este tiempo de espera cuando ejecuto esta consulta junto con otras consultas. El tiempo de espera siempre ocurre en la misma llamada.

El último elemento me hizo pensar que estoy atrapando un punto muerto en el lado de la base de datos: la consulta está bloqueada por un bloqueo y el tiempo de espera expira, matando la conexión estancada.

El problema con esta idea es que estoy solo haciendo selecciones en el DataContext que está causando problemas. (Tengo inserciones que ocurren en una base de datos/DataContexts diferente). Tampoco tengo transacciones explícitas. Esto me hace tropezar un poco: el comportamiento de la consulta se ve exactamente como un punto muerto, pero nunca he tenido un punto muerto que no haya sido causado por algún tipo de problema de aislamiento de transacción, y ese no es el caso aquí (a primera vista de todos modos).

Estoy buscando consejos sobre cómo solucionar este problema. ¿Qué tipo de cosas debería considerar para determinar la causa de este problema?

EDITAR

Algunas notas que pueden ser útiles:

  • estoy consulta contra una vista que hace referencia:
    • Otros puntos de vista en la misma base de datos
    • sinónimos que apuntan a tablas en otra base de datos a través de un servidor vinculado.
  • Este punto de vista está utilizando union a unirse a los resultados de varias consultas juntos

Epílogo

terminé de arreglar el problema central de reelaboración de mi consulta. El original llamaba algunas tablas más de una vez (a través de diferentes vistas). La versión modificada pasó por alto todo esto y los tiempos de espera desaparecieron.

+0

cuando dice 'Ejecutar el SQL equivalente en SQL Management Studio' ¿quiere decir que está copiando el SQL real generado por LINQ de la salida de depuración? también: dado que tiene acceso a la base de datos, ¿puede aislar y monitorear el proceso real mientras se ejecuta en el Monitor de actividad? –

+0

¿Ha ejecutado SQL Profiler al mismo tiempo que se está produciendo el problema? –

+0

@E Rolnicki: Sí, obteniendo el SQL real de LINQ. –

Respuesta

4

ejecute el código de nuevo desde la aplicación, mientras se está a la espera (durante 2 minutos ??) ejecutar esto en una ventana de consulta:

;with Blockers AS 
(SELECT 
    r.session_id AS spid 
     ,r.cpu_time,r.reads,r.writes,r.logical_reads 
     ,r.blocking_session_id AS BlockingSPID 
     ,LEFT(OBJECT_NAME(st.objectid, st.dbid),50) AS ShortObjectName 
     ,LEFT(DB_NAME(r.database_id),50) AS DatabaseName 
     ,s.program_name 
     ,s.login_name 
     ,OBJECT_NAME(st.objectid, st.dbid) AS ObjectName 
     ,SUBSTRING(st.text, (r.statement_start_offset/2)+1,((CASE r.statement_end_offset 
                    WHEN -1 THEN DATALENGTH(st.text) 
                    ELSE r.statement_end_offset 
                   END - r.statement_start_offset 
                  )/2 
                  ) + 1 
        ) AS SQLText 
    FROM sys.dm_exec_requests       r 
     JOIN sys.dm_exec_sessions      s ON r.session_id = s.session_id 
     CROSS APPLY sys.dm_exec_sql_text (sql_handle) st 
    --WHERE r.session_id > 50 
) 
SELECT Blockers.* FROM Blockers 

le mostrará todos los bloques en el momento de la carrera .

+0

Esa es una pregunta interesante, pero no creo que obtenga información útil de ella. Cuando lo ejecuto durante la "pausa" de la ejecución de la consulta antes del tiempo de espera, obtengo 2 filas. Uno es para esta consulta en sí, y el otro es para la consulta que causa el tiempo de espera. En este último, obtengo un BlockingSPID de 0, y no veo ninguna otra información en la fila que indique lo que se está bloqueando. –

+0

eso significa que NO está esperando un candado, que es el 'útil' –

0

¿Está seguro de que los recursos no recogidos no consumen el conjunto de conexiones?

Pruebe envolviendo su SqlDataContext en un bloque en uso y vea si el problema persiste.

+0

Mi DataContext ya está en un bloque de uso, pero su vida útil se extiende a muchas docenas de consultas (es decir, la duración de la aplicación). ¿Cómo puedo verificar qué recursos no recogidos existen? –

Cuestiones relacionadas