 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Vie 18 Ene, 2008 12:59 am Asunto: Error si falla la red |
|
|
Tengo un problema con Interbase trabajando en RED.
Si mi aplicación está conectada a una BDD que se encuentra en otro PC de la RED y esta, se desconecta por un fallo en la red eléctrica, o la Red se cae durante mas de 50 milisegundos por cualquier motivo, como desconectar el cable de red, mi aplicación me da el siguiente error:
Unable to complete network request to host “Barebone:3050”.
Error reading data from the connection.
Se ha forzado la interrupción de una conexión existente por el host remoto.
Este Error lo capturo de este modo con el ‘EIBInterBaseError’ de la siguiente manera:
| Código: |
//En el Form de Base de datos pongo esto:
__fastcall TMDatos::TMDatos(TComponent* Owner)
: TDataModule(Owner)
{
Application->OnException = ErrorServidor;
}
|
Y la funcion ‘ErrorServidor’ contiene esto:
| Código: |
void __fastcall TMDatos::ErrorServidor(TObject *Sender, Exception *E)
{
//si es una excepcion de interbase
if(E->ClassNameIs("EIBInterBaseError"))
{
EIBInterBaseError *ErrorIB = reinterpret_cast<EIBInterBaseError>(E);
// si realmente es de interbase, tratamos el codigo de error
if(ErrorIB->SQLCode == -902)
{
ShowMessage(
"Su RED ha sufrido un Corte de Luz,\n"
"o su RED no es Consistente contra Fallos de Conexión.\n\n"
"TPVBarman Pro, tiene que desconectarse del Servidor.\n"
"Saldrá del Programa, para evitar un mal mayor.");
Application->Terminate();// Salir del programa con Error
exit(0);
}
}
else
ShowMessage(E->Message);
}
|
Con esta función capturo el error -902 de ErrorIB->SQLCode,
Tambien puedo capturar el error en si mismo comprobando el valor devuelto por ‘ErrorIB->IBErrorCode’ que es 335544721 así:
| Código: |
If(ErrorIB->IBErrorCode == 335544721)
{
//Intenta conectar otra vez.
}
|
El problema es que si sigo insistiendo el programa de da otro error del Builder que dice:
‘Dataset open’
Resumiendo:
¿Como puedo hacer para que si La RED se cae por cualquier motivo, mi aplicación vuelva a funcionar cuando la red vuelva a ser operativa?
Lo que me gustaría hacer es esto:
| Código: |
void __fastcall TMDatos::ErrorServidor(TObject *Sender, Exception *E)
{
//si es una excepcion de interbase
if(E->ClassNameIs("EIBInterBaseError"))
{
EIBInterBaseError *ErrorIB = reinterpret_cast<EIBInterBaseError>(E);
// si realmente es de interbase, tratamos el codigo de error
if(ErrorIB->SQLCode == -902)
{
if(MessageDlgPos("TPVBarman Pro...\n\n"
"Su RED ha sufrido un Corte de Luz,\n"
"o su RED no es Consistente contra Fallos de Conexión.\n\n"
"¿Quiere Reintentar la Conexión?"",
mtConfirmation, TMsgDlgButtons() << mbNo <<mbOK>Left + 290, frmVentas->Top + 300)== mrOk)
{
IBDatabase->Close();
IBDatabase->Open();
}
else
{
Application->Terminate();// Salir del programa con Error
exit(0);
}
}
}
} |
Pero no funciona. Alguna Sugerencia al respecto... _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Jue 31 Ene, 2008 8:05 am Asunto: |
|
|
Hola Jésus, este post no lo había visto.
Mira a veces es casi imposible detectar cuando el cable de red ha fallado pues este tema es el "Media Sense" de Windows, pero he realizado una trampa cuando se esta Accediendo a la parte de Edición es decir cuando el usuario esta en el proceso de grabación que bien puede servirte para lo que estas implementando, te explico mi problema y la manera de como solucionarlo.
Uno de los problemas que encontre cuando intenté trasferir 165 mil registros de una base de Dbase a Interbase/Firebird
Fueron los siguientes.
Cuando estaba transfiriendo la información en un equipo, este tardaba aproximadamente 3 hrs, así que desidí instalar una maquina Virtual (Virtual PC 2007 de Windows o VMWare de prueba) para crear un segundo equipo usando parte del HardWare del mio.
realizando la prueba y dividiendo el numero de registros. inicio las transferencias, la mitad de registros en el mio y la otra mitad de registros en el equipo virtual conectados a la misma base ( una mini red funcionable)
cuando uno de los equipos termina pues ha transferido todos, me di cuenta que en el otro equipo, me saltaba una excepción indicandome que no estaba en modo Edicion. me extrañé pues según mi programación la forma de hacerlo es correcta.
Revisé y revisé y el código estaba correcto. no asi, cuando detectaba que la red se habia desconectado o se aplicaban las transferencias. pues al cerrar en una Estacion, la otra automaticamente tambien cerraba las transacciones (uso eventos para notificar que hay cambios y asi reflejarlos directamente en TODAS las estaciones).
para no hacer grande este post, tuve el mismo problema que mencionas, y dije "mmm con try ... catch" pero no sabia como meterlo. asi que decidi hacer lo siguiente.
Analicé mi algoritmo y esto era lo que hacia.
| Código: | 1.- abrir la tabla de Dbase
2.- ir al primer registro de la tabla de Dbase
3.- Ejecutar hasta que no llegue al final de la tabla de Dbase.
4.- Insertar un registro en la tabla de Interbase-firebird (previa apertura)
5.- Actualizar los campos en la tabla de Int-Fire, con la info de la T-Dbase
6.- Grabar en interbase-Firebird (post, applyupdate, commitretainig)
7.- Ir al siguiente Registro de la tabla de Dbase (next)
8.- Fin del ciclo del punto (3) |
Según yo, esto era lo correcto y a simple vista así es.
pero cuando una de las estaciones terminaba, cerraba la transaccion antes que la otra terminara, saltandome una excepcion en el punto 5 del algoritmo diciendome que la red se habia perdido o que no estaba en modo edicion.
A fin de cuentas lo que hice fue lo siguiente, agregue un nuevo ciclo de la siguiente manera
| Código: | 1.- abrir la tabla de Dbase
2.- ir al primer registro de la tabla de Dbase
3.- Ejecutar hasta que no llegue al final de la tabla de Dbase.
4.- Insertar un registro en la tabla de Interbase-firebird (previa apertura)(Edit() o Insert())
while(1) // ejecutar siempre
{
try
{
// si hay un error lo atrapo y me voy al catch(...)
5.- Actualizar los campos en la tabla de Int-Fire, con la info de la T-Dbase
6.- Grabar en interbase-Firebird (post, applyupdate, commitretainig)
// si llegaba a este punto quiere decir que el registro
// se ha grabado correctamente por lo tanto se interrumpe
// el ciclo infinito.
break; // al salir ivamos al next para el siguiente registro
// de la tabla de Dbase paso No. 7
}
catch(...)
{
// aqui capturaba la exepcion, pero lo unico que hacia, es
// activar nuevamente la edicion
TablaFirebird->Edit();
}
}
7.- Ir al siguiente Registro de la tabla de Dbase (next)
8.- Fin del ciclo del punto (3) |
y asi fue como solucioné el error de la conexion cortada o de conflictos
dentro de las tablas cuando una terminaba, pues este ciclo infinito
while(1) hace que la tabla siempre este en modo edicion.
en tu caso puedes hacer lo mismo y validar con un MessageDlg() == <Resultado boton>
dentro de la parte del catch(...) y mostrarle al usuario algo como
| Código: | |-----------------------------------------|
| (!) La red se ha caido |
| |
| [Reintentar] [Cancelar] |
|-----------------------------------------| |
Si elige el boton Cancelar pues usas un break para salir del ciclo
y un rollback para cancelar las transacciones pendientes.
si desides usar el Reintentar pues no haces nada y lo regresas al ciclo
infinito.
Espero que esta pueda darte una idea y por que no una solucion al problema del cable caído o "No esta en modo Edit"
Saludos. _________________
 |
|
| Volver arriba |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Jue 31 Ene, 2008 2:25 pm Asunto: |
|
|
Gracias Cesar, ya habia implementado algo parecido con un mensaje al usuario, "Cancelar Reintentar".
Ahora estoy aprendiendo PHP. Saludos. _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|