none
Continúo con error Timeout expired. RRS feed

  • Pregunta

  • Hola amigos del foro, continúo con el error: "Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding".  Estoy usando VB.Net 2012, Sql Server Standard 2014.
    La consulta que hago desde un procedimiento almacenado, es un poquito compleja, donde veo las compras realizadas por los clientes cada mes, los pagos que realizan cada mes y veo el saldo y otras cosas.

    Cuando hago las pruebas de los procedimientos que tengo armados desde el Server Management, obtengo los resultados inmediatamente. El problema es cuando ejecuto estos procedimientos desde el programa, se tarda cada vez mas a medida que avanzo mes a mes.
    He probado para ver si tengo un mejor resultado agregando en la cadena de conección: Min Pool Size = 100;Connect Timeout=500;  Comencé con Min Pool Size = 10;Connect Timeout=30; Y todo sin cambios.
    También encontré en este enlace
    https://support.microsoft.com/es-es/help/2605597/fix-time-out-error-when-a-mirrored-database-connection-is-created-by-t  donde explica que probablemente se deba a: "Este problema se resuelve en el.NET Framework 4.5.2. Además el 4.5.2 de.NET Framework,  hay revisiones disponibles para otras versiones de.NET Framework como se describe en la sección siguiente."

    Ya no se que hacer y espero alguien pueda ayudarme.

    Gracias a todos.

    lunes, 17 de julio de 2017 5:24

Respuestas

  • Esperando no haber equivocado en escribir el código todo lo que adjuntas podrías reducirlo a lo siguiente:

    DECLARE @SucursalID int = 1;
    DECLARE @FechaDePago date = '20170701';
    
    WITH PagosRealizados AS
    (
        SELECT SucursalID, CreditoID, SUM(Monto) AS TotalPagos, MAX(FechaDePago) AS FechaUltimoPago
        FROM PagosEFectuados
        WHERE SucursalID = @SucursalID AND FechaDePago <= @FechaDePago
        GROUP BY SucursalID, CreditoID
    )
    SELECT
        MONTH(ch.FechaDesembolso) AS Periodo, 
        SUM(ch.TotalCredito - COALESCE(pr.TotalPagos, 0)) AS CreditoVencido
    FROM
        dbo.qryCreditosHead ch
        LEFT JOIN PagosRealizados pr ON ch.CreditoID = pr.CreditoID
    	   AND ch.SucursalID = pr.SucursalID
    	   AND (ch.TotalMonto - COALESCE(pr.TotalPagos, 0)) > 0
    WHERE
        ch.FechaDesembolso <= @FechaDePago AND ch.FechaVencimiento <= @FechaDePago
    GROUP BY 
        ch.SucursalID, MONTH(ch.FechaDesembolso);
    GO

    La idea -como te mencione- es que la consulta de selección retorne el resultado de todos los meses, revisa el código y realiza las modificaciones que consideres oportunas.



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.


    lunes, 24 de julio de 2017 3:48

Todas las respuestas

  • ¿El error te lo da al abrir la conexión o al ejecutar la consulta?

    Si es en el 2º punto utiliza la propiedad CommandTimeOut:
    https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout.aspx


    Saludos, Javier J

    lunes, 17 de julio de 2017 6:41
  • Usa el comando en tu SQLcommand
    tuSqlcommand.CommandTimeout = 0

    Te aconsejaria hacer un hilo ... que se genere en segundo plano o inhabilitar los formularios , o sino con un progress bar .

    


    Pasa los puntos prro v:

    lunes, 17 de julio de 2017 13:55
  • Hola  Javier Jimenez y AUTIS por la ayuda. El error de coneccion se me da al ejecutar la consulta. Tengo todavia tres dudas que necesito resolver: ¿Por que en el Sql Server Management la repuesta es inmediata y desde el programa no lo es? No termino de entender esa diferencia en el tiempo de repuesta, lo que me lleva a la segunda pregunta, ¿Es necesario algun parche como se indica en el enlace que puse al inicio de mi pregunta? La ultima es que si al poner en mi codigo el Sqlcommand.CommandTimeout, ¿tengo que quitar de mi cadena de coneccion el Min Pool Size y Connect Timeout?

    Muchas gracias a todos por la ayuda y su valioso tiempo.

        
    • Editado Carlos Cuenta lunes, 17 de julio de 2017 16:17 Reedicion
    lunes, 17 de julio de 2017 16:08
  • mmm es por que ya realizaste esa consulta varias veces ya que esta en memoria no demora mucho pero si un procedimiento o consulta demora mas de 1 minuto tienes que controlar eso pues tu aplicacion estara en el clasico 'No responde'.

    Sube tu procedimiento  o consulta talves se pueda mejorar. ! Slds


    Pasa los puntos prro v:



    lunes, 17 de julio de 2017 16:14
  • Gracias Autis por la repuesta, luego te envio el procedimiento que me esta causando probemas. Este procedimiento desde el Sql Management responde en menos de dos segundos. ¿Puedo mandarlo a algun email?

    Saludos y gracias nuevamente.


    lunes, 17 de julio de 2017 16:33
  • Puedes postearlo aqui mismo.

    feedeandoando@gmail.com


    Pasa los puntos prro v:

    lunes, 17 de julio de 2017 16:36
  • Excelente Autis, dame chance para enviarte todo. Muy agradecido.
    lunes, 17 de julio de 2017 16:38
  • Para mostrarlos en este foro, estuve preparando los procedimientos que me dan problemas con el Timeout Expired, descubrí que el error no está ahi, sino en cómo hago las lecturas de las consultas. Voy a tratar de explicar lo mejor que pueda y a ver si alguien puede indicarme donde está mi error. 

    Para comenzar, tengo dos tablas principales, donde guardo las ventas al credito a los clientes: Cliente, MontoVenta, FechaDeCompra y FechaDeExpiracion. Tengo otra tabla donde tengo todos los pagos realizados por esos clientes: Cliente, FechaDePago, MontoDePago.

    Tengo que mostrar en una grid, por mes en el periodo del año, las ventas con sus pagos respectivos, los que ya no estan vencidos y los que estan vencidos. El procedimiento (resumido) lo hago de la siguiente forma:

    Private Sub CrearResumen (version 1)
    MesProc=1
    Do

        Using OData = New DataOrigen
            'Aqui obtengo la suma de las ventas al credito vencidas
                TotalCreditoVencido = OData.CreditoVencido(MesProcAñoDeProceso)
        End Using
        Using OData = New DataOrigen
            'Aqui obtengo la suma de las ventas al credito no canceladas y no vencidas
                TotalCreditoNoVencido = OData.CreditoNoVencido(MesProcAñoDeProceso)
        End Using
    Loop Until MesProc=12

    End Sub     

    Y es de esta forma, que cuando voy por el septimo o noveno mes me da el error de tiempo de expiracion.
    En algunos rarísimos casos termina el proceso sin problemas, lento, pero sin errores.

    Pero se me ocurrió hacer unos cambios y lo cambié de la siguiente forma:

    Private Sub CrearResumen (version 2)
       Using OData = New DataOrigen
        MesProc=1
        Do

               'Aqui obtengo la suma de las ventas al credito vencidas
               TotalCreditoVencido = OData.CreditoVencido(MesAñoDeProceso)
               'Aqui obtengo la suma de las ventas al credito no canceladas y no vencidas
                TotalCreditoNoVencido = OData.CreditoNoVencido(MesAñoDeProceso)
            Loop Until MesProc=12
       End Using
    End Sub

    Y aquí puedo hacer el resumen en una fracción de tiempo super menor.
    ¿No se supone que la primera forma es la correcta?  ¿Que tiene que ver el Pool Size con esto?                                                                             

    Saludos a todos y gracias.

    Nota: Por cuestiones de espacio muestro cómo incremento MesProc desde 1 a 12 y cómo lo transformo en MesAñoDeProceso.

                                                           
    martes, 18 de julio de 2017 2:47
  • Tal como lo recomendé -en un post anterior que escribiste- no deberías manipular los valores de los atributos que tienen que ver con el pool de conexiones si no tienes alguna razón y conocimiento del impacto de los cambios, los valores que vienen por defecto son suficientes para tener controlado de manera eficiente los accesos a la base de datos.

    Respecto al código que adjuntas, no puedo dar mi punto de vista porque no muestras el código de los métodos donde precisamente radica el meollo del asunto, lo que si queda claro es que no es lo mismo acceder una sola vez a la base de datos que hacerlo 24 veces (2 veces por cada mes).

    Sin embargo, no necesitas ejecutar 24 operaciones contra la base de datos si puedes hacerlo en una sola operación, ¿puedes adjuntar las tablas que participan en la consulta de selección y además los resultados que esperas?


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 18 de julio de 2017 5:19
  • Gracias por responder Williams Morales, no pude adjuntar los códigos por cuestiones de trabajo. El dia de mañana voy a tener tiempo. Me interesa saber cómo realizar todo con menos operaciones. Voy a subir en este foro los códigos en forma resumida, si puedes, por favor dame tu email para enviarte los códigos completos. 

    Muy agradecido.

                                             
    • Editado Carlos Cuenta martes, 18 de julio de 2017 23:04 corrección
    martes, 18 de julio de 2017 21:57
  •  Estimado  A U T I S,  te envié los codigos completos a tu email, cualquier ayuda la seguimos en el foro.

    Willams Morales mandame tu email también para enviarte los códigos completos. 

    Saludos a todos.

                                                                       
                         
    miércoles, 19 de julio de 2017 17:38
  • He cambiado un poco el código y he logrado reducir el tiempo de proceso, pero tengo todavía algunas dudas. Para Willams Morales, me interesa darle seguimiento a lo que escribistes:"Sin embargo, no necesitas ejecutar 24 operaciones contra la base de datos si puedes hacerlo en una sola operación, ¿puedes adjuntar las tablas que participan en la consulta de selección y además los resultados que esperas?". Envíame tu email para darte los códigos completos y seguir la ayuda en el foro.

    Saludos a todos.

    jueves, 20 de julio de 2017 19:59
  • Ni modo, tiro la toalla. No pude resolver esto.

    ¿Cómo armar los datos automáticamente en el Sql Server? Y ya tenerlos listos, sólo de leer los resultados.

    Ahora sí necesito ayuda.

    Saludos.

    • Editado Carlos Cuenta viernes, 21 de julio de 2017 4:20 Edición.
    viernes, 21 de julio de 2017 1:49
  • Vamos! adjunta los procedimientos almacenados o en caso se trate de información sensible que no deseas publicar crea un escenario "en menor escala" con tablas y datos de prueba, luego indícanos que es lo que buscas obtener y lo resolvemos de inmediato, luego aplicas lo mismo a tu caso.


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    viernes, 21 de julio de 2017 4:24
  • El objetivo es realizar un resumen de los créditos vencidos y no vencidos en el año.

    Periodo

    Crédito Vencido

    Crédito NO Vencido

    Ene-2017 (al 31 de Ene)

    1,000.00

    5,000.00

    Feb-2017 (al 28 de Feb)

    2,000.00

    5,000.00

    Mar-2017

     

     

     

     

    Dic-2017

     

     

     

     Para realizar esto, hago un loop para comenzar desde el mes 1 al 12, resumido para que alcance sin problemas.

     

    Private Sub CrearResumen

      MesProc=1 Do    

        Using OData = New DataOrigen        
          'Aqui obtengo la suma de las ventas al credito vencidas             
          TotalCreditoVencido = OData.CreditoVencido(MesProcAñoDeProceso)     
       End Using     
     
        Using OData = New DataOrigen         
        'Aqui obtengo la suma de las ventas al credito no canceladas y no vencidas             
        TotalCreditoNoVencido = OData.CreditoNoVencido(MesProcAñoDeProceso)     
        End Using
      Loop Until MesProc=12


       'Aquí voy cargando estos valores a el datagridview
    End Sub

     

    Public Function CreditosVencidosT (ByVal LaFecha As Date) As Decimal

           

            Dim CreditoVencido As Decimal = 0

     

            Dim cmd As New SqlCommand("mpa_CreditosVencidosT", MyConec)

            cmd.CommandType = CommandType.StoredProcedure

            cmd.CommandTimeout = 2000  '¡¡¡Qué locura !!!

            cmd.Parameters.Clear()

            cmd.Parameters.AddWithValue("@SucursalID", SqlDbType.TinyInt).Value = vp.SucursalID

            cmd.Parameters.Add("@FechaDeCierre", SqlDbType.Date).Value = LaFecha

     

            Try

                CreditoVencido = CDec(cmd.ExecuteScalar)

            Catch ex As Exception

                CreditoVencido = 0

                RaiseEvent OnError("Error En mpa_CreditosVencidosT ", ex.Message)

            End Try

     

            Return CreditoVencido

     

    End Function

     

     En la Tabla CreditosDet (Detalle de pagos de cuotas del credito) se graban las cuotas a pagar (NoCuota) y el valor de cada cuota a pagar (CuotaAPagar) del crédito de compras dada la cliente y su fecha en que tienen que pagarse esa cuota a más tardar (FechaAPagar). FechaDePago es la fecha en que se realizó el pago y el campo CuotaPagada es cuánto pagó, hay clientes que pagan de más o pagan de menos de la cuota que les corresponde en la fecha. Y sí, Willams Morales no lo quería subir porque pueden decir algo en la oficina por publicar cosas de la empresa, por eso pedía tu email, pero la repuestas seguirlas en el foro.

     

    fnt_CuotasALaFecha

    ***************************

    Selecciono las cuotas pagadas hasta determinada fecha de cierre

    ***************************

     @SucursalID smallint,

     @FechaAPagar  as DATE

    RETURNS TABLE

    AS

    RETURN

     

    SELECT SucursalID, CreditoID, NoCuota, FechaAPagar, CuotaAPagar, FechaDePago, CuotaPagada

    FROM CreditosDet

    WHERE SucursalID=@SucursalID AND FechaAPagar<=@FechaAPagar

     

     

     fnt_CuotasALaFechaSuma

    ***************************

    Aquí totalizo las cuotas pagadas por cada crédito a la fecha de cierre seleccionada

    ***************************

     @SucursalID smallint,

     @FechaAPagar  as DATE

    RETURNS TABLE

    AS

    RETURN

     

    SELECT SucursalID, CreditoID, COUNT(NoCuota) AS NoCuotasPagadas,

           SUM(CuotaAPagar) AS CuotaAPagarT, SUM(CuotaPagada) AS CuotaPagadaT,

                       Max(FechaDePago) AS UFPago

    FROM fnt_CuotasALaFecha(@SucursalID, @FechaAPagar)

    GROUP BY SucursalID, CreditoID

     

     

    **************************

    En la tabla PagosEFectuados se graban los pagos efectuados a los créditos, Monto y Fecha. En un proceso

    posterior se aplican estos pagos a las cuotas en la tabla CreditosDet.

    **************************

     

    fnt_PagosALaFecha

    ***************************

    Se seleccionan los pagos realizados a la fecha de cierre.

    ***************************

     @SucursalID smallint,

     @FechaDePago  as DATE

    RETURNS TABLE

    AS

    RETURN

     

        SELECT SucursalID, TipoMov, FechaDePago, CreditoID, Monto

        FROM PagosEFectuados

        WHERE SucursalID=@SucursalID AND FechaDePago<=@FechaDePago

     

     fnt_PagosALaFechaSuma

    ********************************

    Se totalizan los pagos realizados por créditos a la fecha de cierre.

    ********************************

     @SucursalID smallint,

     @FechaDePago as date

    RETURNS TABLE

    AS

    RETURN

     

    select SucursalID, CreditoID, sum(Monto) as TotalPagos, MAX(FechaDePago) AS FechaUltimoPago

    FROM fnt_PagosALaFecha(@SucursalID, @FechaDePago)

    group by SucursalID, CreditoID

     

     

     

    fnt_EstadoCreditosALaFecha

    ********************************

    Esta función la ocupo para usarla en otros procesos, para este resumen que estoy mostrando, no ocupo todos los campos.

    En CreditosHead solamente está el total del crédito, cuantas cuotas tiene para pagar y datos personales

    ********************************

     @SucursalID smallint,

     @FechaTope  as DATE

     

    RETURNS TABLE

    AS

    RETURN

     

    SELECT dbo.qryCreditosHead.SucursalID, dbo.qryCreditosHead.CreditoID,

           dbo.qryCreditosHead.ClienteID, dbo.qryCreditosHead.ClienteNombresApells,

           dbo.qryCreditosHead.FechaVencimiento, 

           dbo.qryCreditosHead.TotalCredito,

           dbo.qryCreditosHead.NoCuotas,

           fnt_CuotasALaFechaSuma_1.NoCuotasPagadas, 

           fnt_CuotasALaFechaSuma_1.CuotaAPagarT,

           fnt_CuotasALaFechaSuma_1.CuotaPagadaT, UFPago,

           ISNULL(fnt_agosALaFechaSuma_1.TotalPagos,0) AS TotalPagos,

           (dbo.qryCreditosHead.TotalMonto-ISNULL(fnt_PagosALaFechaSuma_1.TotalPagos,0)) AS Saldo,

           (fnt_CuotasALaFechaSuma_1.CuotaAPagarT-ISNULL(fnt_PagosALaFechaSuma_1.TotalPagos,0)) AS Faltante,

           ((fnt_CuotasALaFechaSuma_1.CuotaAPagarT-ISNULL(fnt_PagosALaFechaSuma_1.TotalPagos,0))/dbo.qryCreditosHead.ValorCuota) AS CuotasFalta

    FROM dbo.qryCreditosHead LEFT OUTER JOIN

         dbo.fnt_CuotasALaFechaSuma(@SucursalID,@FechaTope) AS fnt_CuotasALaFechaSuma_1 ON dbo.qryCreditosHead.CreditoID = fnt_CuotasALaFechaSuma_1.CreditoID AND

         dbo.qryCreditosHead.SucursalID = fnt_CuotasALaFechaSuma_1.SucursalID LEFT OUTER JOIN

         dbo.fnt_PagosALaFechaSuma(@SucursalID,@FechaTope) AS fnt_PagosALaFechaSuma_1 ON dbo.qryCreditosHead.CreditoID = fnt_PagosALaFechaSuma_1.CreditoID AND

         dbo.qryCreditosHead.SucursalID = fnt_PagosALaFechaSuma_1.SucursalID

    WHERE dbo.qryCreditosHead.SucursalID=@SucursalID

     

     

     

    Y desde este procedimiento procedo mes a mes con el cálculo de los créditos vencidos y no vencidos.

    mpa_CreditosVencidosT

    ********************************

    Aquí sumo el saldo de los créditos vencidos (FechaVencimiento<=@FechaDeCierre), los créditos no vencidos es lo inverso FechaVencimiento>@FechaDeCierre

    ********************************

    @SucursalID smallint,

    @FechaDeCierre date

     

    AS

    BEGIN

                                              

        SELECT Sum(TotalCredito)- Sum(TotalPagos) AS DiferenciaT

        FROM dbo.fnt_EstadoCreditosALaFecha(@SucursalID,@FechaDeCierre)

        WHERE Saldo>0 AND FechaDesembolso<=@FechaDeCierre  AND FechaVencimiento<=@FechaDeCierre

        Group BY SucursalID

    END

     

    viernes, 21 de julio de 2017 14:45
  • Ojalá el lunes tenga más suerte, sigo sin resolver y el tiempo se acaba.

    ¡¡¡AYUDA!!!

    domingo, 23 de julio de 2017 20:26
  • No te quiero complicar más aún, asi que si no lo ves viable, ni puto caso me hagas, por que no quietas ese Try a ver si da alguna falla encubierta? o al caso todos los Try que contengan el programa.

    Saludos y suerte

    domingo, 23 de julio de 2017 22:48
  • Esperando no haber equivocado en escribir el código todo lo que adjuntas podrías reducirlo a lo siguiente:

    DECLARE @SucursalID int = 1;
    DECLARE @FechaDePago date = '20170701';
    
    WITH PagosRealizados AS
    (
        SELECT SucursalID, CreditoID, SUM(Monto) AS TotalPagos, MAX(FechaDePago) AS FechaUltimoPago
        FROM PagosEFectuados
        WHERE SucursalID = @SucursalID AND FechaDePago <= @FechaDePago
        GROUP BY SucursalID, CreditoID
    )
    SELECT
        MONTH(ch.FechaDesembolso) AS Periodo, 
        SUM(ch.TotalCredito - COALESCE(pr.TotalPagos, 0)) AS CreditoVencido
    FROM
        dbo.qryCreditosHead ch
        LEFT JOIN PagosRealizados pr ON ch.CreditoID = pr.CreditoID
    	   AND ch.SucursalID = pr.SucursalID
    	   AND (ch.TotalMonto - COALESCE(pr.TotalPagos, 0)) > 0
    WHERE
        ch.FechaDesembolso <= @FechaDePago AND ch.FechaVencimiento <= @FechaDePago
    GROUP BY 
        ch.SucursalID, MONTH(ch.FechaDesembolso);
    GO

    La idea -como te mencione- es que la consulta de selección retorne el resultado de todos los meses, revisa el código y realiza las modificaciones que consideres oportunas.



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.


    lunes, 24 de julio de 2017 3:48
  •   Willams Morales , muy y de veras, muy agradecido. Voy a probar hoy esto y luego te cuento. Pero se ve genial.

    Saludos.

    lunes, 24 de julio de 2017 15:41