Foros del Web » Programando para Internet » PHP »

Reconexión Base de Datos

Estas en el tema de Reconexión Base de Datos en el foro de PHP en Foros del Web. Saludos!! Estoy haciendo una serie de scripts en PHP para controlar la entrada y salida de una base de datos MySQL y me encuentro con ...
  #1 (permalink)  
Antiguo 14/12/2008, 14:04
 
Fecha de Ingreso: enero-2005
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 0
Reconexión Base de Datos

Saludos!!

Estoy haciendo una serie de scripts en PHP para controlar la entrada y salida de una base de datos MySQL y me encuentro con el siguiente problema:

Cuando hay algún tipo de error, por ejemplo que el servidor MySQL ha caído, en mis scripts me interesa capturar el número del error y actuar en consecuencia, y así lo hago capturando el código de error con mysql_errno().

El problema es que me he fijado conectándome al servidor de BD por línea de comandos que si, por ejemplo, haces un INSERT y el servidor ha caído, el sistema te envía un primer mensaje de error (nº2006) y luego intenta la reconexión, y si no consigue ésta, te envía el error 2003. Eso es un problema, porqué podría darse que yo capturo el primer error y actuo como si no se hubiera realizado la inserción, y después resulta que el gestor de base de datos en el segundo intento sí que lo inserta y yo ni me entero!!

A alguien se le ocurre una solución a este tema?
  #2 (permalink)  
Antiguo 14/12/2008, 14:31
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Reconexión Base de Datos

Usa transacciones, con eso garantizas la atomicidad de los datos.

Saludos.
  #3 (permalink)  
Antiguo 14/12/2008, 15:01
 
Fecha de Ingreso: enero-2005
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 0
Respuesta: Reconexión Base de Datos

Mmmmmmm

No sé si te entiendo muy bien, hablando concretamente, te refieres a que haga primero el INSERT, luego el COMMIT y después compruebe si ha habido algún error en la inserción, y si resulta que sí lo ha habido, éste ya será definitivo??

ALEX
  #4 (permalink)  
Antiguo 14/12/2008, 15:06
Avatar de Ronruby  
Fecha de Ingreso: julio-2008
Ubicación: 18°30'N, 69°59'W
Mensajes: 4.879
Antigüedad: 16 años, 4 meses
Puntos: 416
Respuesta: Reconexión Base de Datos

Haces el insert, si los datos fueron insertados correctamente haces el COMMIT, de lo contrario haces un ROLLBACK.
  #5 (permalink)  
Antiguo 14/12/2008, 15:32
 
Fecha de Ingreso: enero-2005
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 0
Respuesta: Reconexión Base de Datos

Vale, ya te he entendido GatorV...

El tema es que si yo recojo el error y actuo como si nunca se hubiera insertado el registro, efectivamente así será, porqué no habré hecho el COMMIT....claaaaaaro!

Entonces por lo que veo, cualquier aplicación web medianamente seria que quiera tener un mínimo de garantías frente a caídas del servidor deberá de ser con transacciones verdad?
  #6 (permalink)  
Antiguo 14/12/2008, 16:00
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Reconexión Base de Datos

Asi es por eso todos los sitios "grandes" usan transacciones es la mejor forma para garantizar, que una larga cadena de procesos se ejecuten, por ejemplo imagina una transaccion de banco, que hay que restar y sumar a cuentas, no se pueden quedar las cosas "a medias", para eso es la transaccion.

Saludos.
  #7 (permalink)  
Antiguo 15/12/2008, 14:19
 
Fecha de Ingreso: enero-2005
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 0
Respuesta: Reconexión Base de Datos

Saludos!

Reactivo este tema, porqué sigo sin ver el tema claro. Voy a intentar explicarme bien: en mi script PHP ejecuto un código que esquemáticamente es este:

$result = mysql_query($query,$enlace);
if(!$result) {
$error = mysql_errno($enlace);
mysql_close($enlace);
return $error;
}

De esta manera capturo el error que ha tenido lugar (si es que lo ha tenido) y actuo en consecuencia. El problema era que el servidor MySQL si no puede realizar el query, envía un mensaje de error (el 2006), pero luego LO REINTENTA, enviando 2003 si nuevamente no puede hacerlo y ahí ya sí que termina.

PROBLEMA: si yo capturo el 2006, pero resulta que a la 2ª lo consigue, yo me creo que es un error pero en realidad sí que ha ejecutado el query.

SOLUCIÓN PROPUESTA: Emplear transacciones. Pero sigo viendo el mismo problema, ya que si después de las sentencias anteriores hago algo así:

$result2 = mysql_query("COMMIT",$enlace);
if(!$result2) {
$error = mysql_errno($enlace);
mysql_close($enlace);
return $error;
}

Estamos en las mismas que antes básicamente.... ¿Y si me lanza el primer error, y yo actuo como si hubiera un ídem, pero a la 2ª reconexión se ejecuta el COMMIT y yo ni me entero?

No sé si me explico muy bien, a alguien se le ocurre alguna solución a este tema?

ALEX
  #8 (permalink)  
Antiguo 15/12/2008, 15:23
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Reconexión Base de Datos

Pues en primera no entiendo para que cerrar la conexion despues de un query, en ese caso las transacciones no te van a funcionar.

Te recomiendo uses una capa de abstracción como Zend_Db, para que veas como gestionar tus transacciones a la base de datos.

Saludos.
  #9 (permalink)  
Antiguo 15/12/2008, 15:55
 
Fecha de Ingreso: enero-2005
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 0
Respuesta: Reconexión Base de Datos

Perdona, pero no lo he entendido! Sólo se cierra la conexión en el caso de que el query no haya funcionado... si el query ha resultado, no cierro la conexión, sino que inmediatamente envío el COMMIT....te sabría mal explicármelo un poquito mejor?

Y muchas gracias por tu paciencia!

ALEX
  #10 (permalink)  
Antiguo 15/12/2008, 16:10
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Reconexión Base de Datos

Lo que pasa es que no entiendo para que cerrar la conexion en caso de error, con eso rompes con el flujo de errores, por eso mi recomendacion a usar una libreria de alto nivel con el que puedas controlar excepciones de forma más sencilla.

Saludos.
  #11 (permalink)  
Antiguo 15/12/2008, 16:14
Avatar de Carxl
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: Bogotá
Mensajes: 2.993
Antigüedad: 18 años, 3 meses
Puntos: 70
Respuesta: Reconexión Base de Datos

Hola AlexWeb...

Creo que te estás liando sin necesidad

La lógica es sencilla, si hay error, hay un ROLLBACK, si se llevó a cabo satisfactoriamente la consulta, aplicas COMMIT.

Las transacciones tienen tres instrucciones, BEGIN(comienza una transacción), COMMIT(confirma una transacción), ROLLBACK(quiebra, deshace una transacción).

La idea sería:
Código php:
Ver original
  1. //comienza transacción
  2. $ini_tran="BEGIN;";
  3. $result = mysql_query($ini_tran,$enlace);
  4.  
  5. //se ejecuta query
  6. $query="select * from .... bla bla bla"
  7. $result = mysql_query($query,$enlace);
  8. if(!$result)
  9. {
  10. //si hubo error se ejecuta un rollback
  11.     $error = mysql_errno($enlace);
  12. $fin_tran="ROLLBACK;";
  13. $result = mysql_query($fin_tran, $enlace);
  14.     mysql_close($enlace);
  15. }
  16. else
  17. {
  18. //sino, quiere decir que se ejecutó satisfactoriamente, entonces se confirma
  19. $fin_tran="COMMIT;";
  20.  $result = mysql_query($fin_tran, $enlace);
  21. }

Espero lo entiendas...

Saludos
__________________
Hay 10 tipos de personas, los que entienden binario y los que no. (Anónimo)
www.programandoweb.com
  #12 (permalink)  
Antiguo 15/12/2008, 16:35
 
Fecha de Ingreso: enero-2005
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 0
Respuesta: Reconexión Base de Datos

Pero imagínate una situación muy improbable, pero no imposible, en la que tu query funciona y te va bien, luego envías el COMMIT, pero el gestor te devuelve un error en el envío del COMMIT y resulta que en el reintento el COMMIT se envía bien.....te encontrarías en una fatal situación en la que tú crees que los datos NO han sido confirmados con COMMIT, pero en realidad sí han sido confirmados en el 2º reintento del servidor de base de datos, y tú ni te enterarías, pq a tí sólo te llegaría el primer error, pero no la confirmación acto seguido!!
  #13 (permalink)  
Antiguo 15/12/2008, 16:39
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Reconexión Base de Datos

Pero precisamente para eso es la transaccion, o sea si tu no envias el COMMIT nunca se va a actualizar la informacion, lee sobre el principio de Atomicidad de las bases de datos.

Saludos.
  #14 (permalink)  
Antiguo 15/12/2008, 17:03
 
Fecha de Ingreso: enero-2005
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 0
Respuesta: Reconexión Base de Datos

Lo siento mucho, pero veo que no me estoy explicando nada bien, voy a intentar explicarme mejor:

Cuando envías una petición a mysql, sea la que sea, si el gestor encuentra que no puede conectar con la BD, te envía un primer mensaje de error, pero acto seguido (SIN QUE TU LE ENVIES OTRO QUERY) intenta reconectar y volver a pasar el query, enviándote otro error si de nuevo no lo consigue.

Por tanto, el problema es: ¿Qué pasa si yo le envío el COMMIT para confirmar, y me envía primero un código de error, pero enseguida el gestor lo reintenta y el COMMIT sí que llega al gestor de BD? Será una situación en la que yo he recibido un error, pero los datos SÍ HAN SIDO CONFIRMADOS (ya que el COMMIT que yo envío sí que llega!)

Es decir, no es que yo no envíe el COMMIT, es que sí lo envío, pero me rebota un primer error, y al 2º intento del gestor sí que llega el COMMIT, con lo cual a mí me llega un falso error!!
  #15 (permalink)  
Antiguo 15/12/2008, 20:16
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Reconexión Base de Datos

Pero para eso te conectas antes no?, por eso la atomicidad de la transaccion, creeme que si las transacciones fueran tan volatiles no habria garantia de datos, si tu pones tu script correctamente y pasas el link correcto a la base de datos por tus funciones no vas a tener perdida de datos, ya que el COMMIT va a garantizar que se hagan o no los cambios.

Saludos.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:28.