TMySQLServer():New()

HMG en Español

Moderator: Rathinagiri

Post Reply
User avatar
edufloriv
Posts: 240
Joined: Thu Nov 08, 2012 3:42 am
DBs Used: DBF, MariaDB, MySQL, MSSQL, MariaDB
Location: PERU

TMySQLServer():New()

Post by edufloriv »

Saludos amigos,

Quisiera saber de los que tienen experiencia con MySQL si crean la conexión UNA SOLA VEZ al inicio de su programa o abren la conexión al servidor cada vez que van a realizar una query (oServer := TMySQLServer():New()). Se los pregunto porque me está pasando que esporadicamente mi conexión al MySQL remoto se pierde y en alguna ocasiones incluso se cierra el programa sin mostrar ningún mensaje de error. En otras ocasiones si me muestra un mensaje de error "server has gone away".

En mi caso estoy conectandome una sola vez al inicio del programa:

Code: Select all

PROC INIMYSQL(lForzar)

LOCAL aDataConect , cSqlURL , cSqlUSR , cSqlPSW , cSqlDB

   IF lForzar = NIL
      lForzar := .F.
   ENDIF

   IF ! FILE('Imagen\Conector.txt')
      msgexclamation('No se encontró el archivo de conexión a la base de datos.')
      Win_InfoFarma.Release
   ENDIF

   aDataConect := Txt2Array( 'Imagen\Conector.txt' )
   cSqlURL := hb_decrypt( aDataConect[1] )
   cSqlUSR := hb_decrypt( aDataConect[2] )
   cSqlPSW := hb_decrypt( aDataConect[3] )
   cSqlDB  := hb_decrypt( aDataConect[4] )
   
	// Connect

	oServer := TMySQLServer():New( cSqlURL , cSqlUSR , cSqlPSW )

	// Check For Error

	If oServer:NetErr()

		MsgStop('ERROR:'+oServer:Error())
		Win_InfoFarma.Release

	Else

      oServer:SelectDB( cSqlDB )
      If oServer:NetErr() 
         Win_InfoFarma.Release
         MsgStop("No se pudo conectar a la BD infofarma: "+oServer:Error() )
      else
         SYS_MYSQL := TIME()
         Win_InfoFarma.StatusBar.Item(1) := 'Conectado.'
      Endif 

	EndIf

RETURN
Y luego para mis querys uso esta estructura:

Code: Select all

PROC HelpMArtiBusca

         qMArti := "SELECT * "+;
                   "FROM articulos "+;
                   "INNER JOIN marcas ON articulo_marca_id = marca_id "+;
                   "WHERE articulo_nombre LIKE '"+RTRIM(cBusqueda)+"%' "+;
                   "ORDER BY articulo_nombre "

	oMArti := oServer:Query( qMArti )
	IF ! oMArti:NetErr()
      FOR q = 1 TO oMArti:LastRec()
         oRow := oMArti:GetRow(q)
         Win_Ayuda_MArti.GrdMArti.AddItem ( {;
         oRow:fieldGet("articulo_id") ,;
         oRow:fieldGet("articulo_nombre") ,;
         oRow:fieldGet("marca_abrev") } )
      NEXT
      Win_Ayuda_MArti.GrdMArti.value := 1
      Win_Ayuda_MArti.GrdMArti.setfocus
   ELSE
      cMsgError := oMArti:Error()
      IF 'server has gone away' $ cMsgError .OR. 'connection' $ cMsgError //<-tuve q poner esto para intentar reconectar en caso de una desconexion fortuita
         INIMYSQL()
         HelpMArtiBusca()
      ELSE
         MsgStop ( oMArti:Error() )
         Win_Ayuda_MArti.TxtBuscar.Setfocus
      ENDIF
   ENDIF
	oMArti:Destroy()

RETURN
Agradeceré me orienten al respecto.


cordiales saludos a todos.

Eduardo Flores Rivas


LIMA - PERU
User avatar
serge_girard
Posts: 3342
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Contact:

Re: TMySQLServer():New()

Post by serge_girard »

Eduardo,

I open connection only when I need it, then do the SQL statements and finally close then connection when finished or on errors. Never problems!

Serge
There's nothing you can do that can't be done...
User avatar
danielmaximiliano
Posts: 2646
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Contact:

Re: TMySQLServer():New()

Post by danielmaximiliano »

Hola Edu : La contrib C:\harbour\contrib\hbmysql contiene una funcion que hace un Ping a MySQL para saber si esta viva la conexion

Code: Select all

HB_FUNC( MYSQL_PING ) /* int mysql_ping( MYSQL * mysql ) */
{
   MYSQL * mysql = hb_MYSQL_par( 1 );

   if( mysql )
      hb_retnint( mysql_ping( mysql ) );
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
eso habria que ver si existe en TMySQL porque en algunos lugares se describe la funcion

https://root.cern.ch/doc/master/classTM ... 6ddcadab60
*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`. Harbour/HMG : It's magic !
(¸.·``··*

Saludos / Regards
DaNiElMaXiMiLiAnO

Whatsapp. := +54901169026142
Telegram Name := DaNiElMaXiMiLiAnO
martingz
Posts: 402
Joined: Wed Nov 18, 2009 11:14 pm
Location: Mexico

Re: TMySQLServer():New()

Post by martingz »

Hola Eduardo mn mi caso solo la abro una sola vez, tienes que mover el tiempo del lado del servidor para que no te cierre la conexion
en mi caso uso

bQuery:=oServer:Query("SET SESSION wait_timeout = 86400")
If bQuery:NetErr()
MsgStop ( bQuery:Error() )
return Nil
Endif

hay mas de 100 equipos mconectador, algunos dejan el sistema abierto por mucho tiempo,(cosa que les dice que no hagan pero lo hacen) y no hemos tenido problemas de desconexion , aqui puedes consultar sobre su uso

https://mariadb.com/docs/reference/mdb/ ... t_timeout/
User avatar
Claudio Ricardo
Posts: 367
Joined: Tue Oct 27, 2020 3:38 am
DBs Used: DBF, MySQL, MariaDB
Location: Bs. As. - Argentina

Re: TMySQLServer():New()

Post by Claudio Ricardo »

Hola Eduardo... Yo hago como Serge salvo cuando envío query's consecutivas.
La función TMySQLServer() admite un cuarto parámetro " port " útil si deseas
conectar mediante uno diferente al 3306 (default).
Corrige al sabio y lo harás más sabio, Corrige al necio y lo harás tu enemigo.
WhatsApp / Telegram: +54 911-63016162
User avatar
edufloriv
Posts: 240
Joined: Thu Nov 08, 2012 3:42 am
DBs Used: DBF, MariaDB, MySQL, MSSQL, MariaDB
Location: PERU

Re: TMySQLServer():New()

Post by edufloriv »

Saludos amigos,

Realicé la consulta con mi proveedor de host y me respondieron que hay actividad inusual en el servidor MySQL y me enviaron esta imagen:
base de datos sleep.jpg
base de datos sleep.jpg (197.34 KiB) Viewed 1538 times
Tambien me enviarion este link:

https://support.sciencelogic.com/s/article/1276

Entiendo que es el tiempo en que una conexión esta abierta al servidor, realicé algunos cambios:

Code: Select all

*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
* FUNCION...: INIMYSQL
* COMENTARIO: CONECTA CON EL SERVIDOR SQL
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------

PROC INIMYSQL(lForzar)

LOCAL aDataConect , cSqlURL , cSqlUSR , cSqlPSW , cSqlDB , cActive

   IF lForzar = NIL
      lForzar := .F.
   ENDIF

   IF SYS_MYSQL > '00:00:00'
      cActive := oServer:Ping()
      IF LENNOSPC(cActive) = 0
         RETURN
      ELSE
         WAIT WINDOW 'Reconectando con el host...'
         oServer:Destroy()
         WAIT CLEAR
      ENDIF
   ENDIF

   IF ! FILE('Imagen\conector.txt')
      msgexclamation('No se encontró el archivo de conexión a la base de datos.')
      Win_InfoFarma.Release
   ENDIF

   aDataConect := Txt2Array( 'Imagen\Conector.txt' )
   cSqlURL := hb_decrypt( aDataConect[1] )
   cSqlUSR := hb_decrypt( aDataConect[2] )
   cSqlPSW := hb_decrypt( aDataConect[3] )
   cSqlDB  := hb_decrypt( aDataConect[4] )
   
	// Connect

	oServer := TMySQLServer():New( cSqlURL , cSqlUSR , cSqlPSW )

	// Check For Error

	If ! oServer:NetErr()

      oServer:SelectDB( cSqlDB )
      If oServer:NetErr() 
         MsgStop("Cannot connect to MySQL: "+oServer:Error() )
         Win_InfoFarma.Release
      else
         SYS_MYSQL := TIME()
         Win_InfoFarma.StatusBar.Item(1) := 'Conectado.'
      Endif 

	Else

		MsgStop('ERROR:'+oServer:Error())
		Win_InfoFarma.Release

	EndIf

RETURN


*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
* FUNCION...: KILLMYSQL
* COMENTARIO: 
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------

PROC KILLMYSQL

	oServer:Destroy()
   SYS_MYSQL := '00:00:00'

RETURN
Es más puse un TIMER para que se fuerce el cierre de la conexion cada 10 minutos:

Code: Select all

      DEFINE TIMER Timer_1 ;
      INTERVAL  600000 ; //10 minutos
      ACTION KILLMYSQL()
Asi, cada que hago una consulta la hago asi:

Code: Select all

   INIMYSQL()
   oSave := oServer:Query( qSave )
   IF ! oSave:NetErr()
      lInserted := .T.
   ELSE
      SQLErrorHost( oSave:Error() )
   ENDIF
   oSave:Destroy()
Sin embargo, se me siguen desconectando TODOS los puntos, el MySQL se desconecta y se me cuelgan todas las terminales. Esto ocurre de manera imprevista, puede ocurrir 3 o 4 veces al día.

Agradeceré cualquier ayuda al respecto.


Cordiales saludos.

Eduardo Flores Rivas


LIMA - PERU
User avatar
vagblad
Posts: 174
Joined: Tue Jun 18, 2013 12:18 pm
DBs Used: MySQL,DBF
Location: Thessaloniki, Greece

Re: TMySQLServer():New()

Post by vagblad »

Hello Eduardo,

You can try executing this query in your program from time to time:

Code: Select all

qMArti :=  "SELECT ID,TIME FROM INFORMATION_SCHEMA.PROCESSLIST "
qMArti += "WHERE TIME > XXXX" //where XXXX put the time in seconds you want a connection to be allowed open
qMArti := oServer:Query( qMArti )
This will return an array of processes and the time being open. from there you can start executing this:

Code: Select all

qMArti := "KILL XXX" //Where XXX the id of the process you want to kill
qMArti := oServer:Query( qMArti )
Vagelis Prodromidis
Email: vagblad@gmail.com, Skype: vagblad
User avatar
edufloriv
Posts: 240
Joined: Thu Nov 08, 2012 3:42 am
DBs Used: DBF, MariaDB, MySQL, MSSQL, MariaDB
Location: PERU

Re: TMySQLServer():New()

Post by edufloriv »

VagBlad,

Thanks so much. Your answer helped me a lot. I found that a specific terminal, for some reason, left a table locked and since I am using MyIsam engine, the rest of the terminals were hung. I could solve it manually by performing a KILL of that process and everything continued normal. I'm going to convert all my tables to InnoDb engine and create a process that "kills" the "Sending Data" connections that are more than 100 seconds long, while identifying the problem of that terminal.
sending_data.png
sending_data.png (44.48 KiB) Viewed 1349 times
------------------------------------------------------------------------------------------------

VagBlad,

Muchas gracias. Tu respuesta me ayudo mucho. Encontré que una terminal especifica, por alguna razón, dejaba bloqueada una tabla, y como estoy usando motor MyIsam, el resto de terminales se colgaban. Lo podia resolver manualmente realizando un KILL de ese proceso y todo continuaba normal. Voy a convertir todas mis tablas a motor InnoDb y crear un proceso que "mate" las conexiones "Sending Data" que tengan más de 100 segundos, mientras identifico el problema de esa terminal.
sending_data.png
sending_data.png (44.48 KiB) Viewed 1349 times

Eduardo Flores Rivas


LIMA - PERU
Post Reply