https://foro.gambas-es.org/viewtopic.php?f=3&t=980
-----------------------------------
karpaga
Viernes, 01 Octobre 2010, 15:55

Problema Con Timeout De Mysql
-----------------------------------
Hola,

  Tengo un problema con mi aplicación, y es que si la dejo ejecutando, al día siguiente me da un fallo del mysql. Lo que pasa es que se pierde la conexión (timeout del mysql). Yo lo que hago es cuando entro al programa abro una conexión y solo la cierro al cerrar el programa, pero si no lo cierro tal y como hago ahora me da el fallo. No se si la mejor solución a esto sería abrir conexión cada vez que vaya a ejecutar una sentencia sql y cerrarla justo después.

¿Que opináis?


-----------------------------------
shordi
Viernes, 01 Octobre 2010, 19:25

Re: Problema Con Timeout De Mysql
-----------------------------------
Personalmente utilizo una clase que extiende la clase connection. La llamo conexion, claro.
El código es éste:
[code linenumbers=false syntax=gambas]

INHERITS Connection

PUBLIC PROCEDURE conectar()
    TRY ME.Close
    TRY ME.Open
    IF ERROR THEN
      Message.Error("Imposible conectar a la base de datos. Error: " & Error.Text & "\n SIRIGAMI finalizará ahora.")
      QUIT
    END IF
END

PUBLIC FUNCTION consulta(OPTIONAL sql AS String, OPTIONAL res AS Result, OPTIONAL modo AS String, OPTIONAL tabla AS String, OPTIONAL campoClave AS String, OPTIONAL clave AS String) AS Result
 
  DIM r AS Result
  DIM cad AS String
  
  IF NOT modo THEN 
    modo = "C"   'C=Consulta; E=Edicion; B=Borrado   C es el modo por defecto
  ENDIF 
  IF res THEN 
      r = res
  ENDIF 

  SELECT CASE modo
    CASE "C"
        IF NOT sql THEN 
            Message.Error("condatos.consulta: Falta consulta a efectuar")
            RETURN r
        ENDIF 
        TRY r = ME.Exec(sql) 
            IF ERROR THEN 
                ME.conectar
                TRY r = ME.Exec(sql) ' a la segunda va la vencida
                IF ERROR THEN 
                    Message.Error("Se produjo el siguiente error:\n" & Error.Text)
                    RETURN r
                ENDIF 
            ENDIF 
    CASE "E" 'Edición de registro
        IF NOT campoClave OR NOT tabla THEN 
            Message.Error("condatos.consulta: Faltan datos para el modo edición")
            RETURN r
        ENDIF 
        cad = campoClave & " = &1"
        TRY r = ME.Edit(tabla, cad, clave)
        
        IF ERROR THEN
            ME.conectar
            TRY r = ME.Edit(tabla, cad, clave) ' a la segunda va la vencida
            IF ERROR THEN 
                    Message.Error("Se produjo el siguiente error:\n" & Error.Text)
                    RETURN r
            ENDIF 
        ENDIF 
        IF r.Count = 0 THEN  'si el registro no existe lo creamos
            TRY r = ME.Create(tabla)
            IF ERROR THEN 
                Message.Error("Se produjo el siguiente error:\n" & Error.Text)
                RETURN r
             ENDIF
              r[campoClave] = clave 'asignamos la clave pasada al campo clave
        ENDIF    
    CASE "B"  'Borrado
        TRY ME.delete(tabla, campoclave, clave)
        IF ERROR THEN     
            ME.conectar
            TRY ME.delete(tabla, campoclave, clave) ' a la segunda va la vencida
            IF ERROR THEN 
                Message.Error("Se produjo el siguiente error:\n" & Error.Text)
                RETURN r
             ENDIF
        ENDIF     
    END SELECT   
    
RETURN r
END 
[/code]

El método conectar no se utiliza desde fuera (aunque se puede). Es lo mismo que el método open, pero con un reintento para asegurarse. Es utilizado 
por el método consulta, que te ejecuta la sentencia sql o te modifica los datos (Añadir, borrar o modificar) devolviendo un objeto Result.
El truco es el invento del TBO se lanza la consulta, si falla es que se ha cortado por time-out o por otras causas y se reintenta la apertura de la conexión y se vuelve a lanzar la consulta. Si vuelve a fallar es que ha pasado algo más raro y se genera el eror (de hecho se aborta a lo bestia el prorama). 
El código es un poco chapuza porque funciona y no me he molestado en hacerlo bonito ni elegante. Si tú lo adecentas, please, súbelo al foro.
La ventaja de utilizar una clase es que puedes tener sin problemas más de una conexión abierta a la misma o a distintas bases de datos simultáneamente.
El ejemplo de uso sería:
[code linenumbers=false syntax=gambas]
       DIM condatos as NEW conexion
       DIM res as Result
       condatos.Type = "mysql"
       condatos.Host = mihost
       condatos.Login = "miusuario"
       condatos.Password = "mipassword"
       condatos.Name = "mibase"
       res=condatos.consulta("Select * from mitabla")
[/code]

Los puretas de la POO dirán que no está bien eso de usar parámetros en lugar de propiedades y demás, pero es que soy así de primitivo y no me aclaro mucho con la POO.

Suerte


