Array
(
)

Reconectar ao banco FB

Sanses
   - 11 fev 2006

Senhores

Tenho um aplicação rodando em rede. O problema é que o servidor onde fica o FB também é utilizado, e as vezes o usário reinicia a máquina fazendo com que todas as outras máquinas percam o acesso ao banco. Como poderia proceder para que quando a aplicação cliente utilizasse o banco, reestabelecer a conexão ? Pois quando o servidor volta a funcionar e o cliente tenta executar alguma operação no banco de dados da erro dizendo que a conexão foi recusada.

obs: fb 1,5, ibx(uso ibx por causa do ibevents, para realizar as atualizações, portanto minha conexão com o banco fica sempre ativa), não tem nenhum firewall ou coisas do gênero.

Sanses


Aroldo Zanela
   - 11 fev 2006

Colega,

Também uso IBX, mas por ser cerca de 40¬ mais rápido que outras métodos. Eu uso um mecanismo de ´ping´ para vigiar o servidor (uma espécie de cão de guarda), e quando acontece uma desconexão/re-conexão eu uso o método TestConected.
Veja um trecho:

#Código


if Ping(EnderecoIP) then
begin
if dmERP.dbERP.TestConnected then
begin



Sanses
   - 11 fev 2006

As vezes estamos tão preocupados com nossos compromissos, prazos e etc, que nos esquecemos de que as soluções mais simples podem ser bem mais funcionais.

Obrigado pela dica Aroldo, eu estou em um ponto que cheguei até a destruir o datamodule e recria-lo de novo :oops:

Mas tenho mais uma dúvida. Quando ocorre a desconexão, a impressão que tenho é que no cliente, a conexão fica presa e não aceita recriar a conexão pois só consigo conectar quando reinicio o cliente. Quando dou um comando DM.IBDB.close ou DM.IBDB.connection := false, ele retorna um erro. Nesta aplicação uso apenas commit, portanto não mantenho transações abertas, portanto a meu ver, bastaria executar um desses 2 comandos, mas quando não aparece o mesmo erro citado anteriormente, a aplicação trava, e nesse caso o ping detectaria que o servidor não está online, mas como eu reconectaria ?? A mensagem que retorna é que o host recusou a conecão - alguma coisa assim, já to até misturando as mensagens de erro.

Para ser mais claro, o ping resolve o problema para saber quando reconectar. Mas como posso reconectar ?

Grato pela Atenção
Sanses


Aroldo Zanela
   - 11 fev 2006

Colega,

O Método TestConected é que vai ´limpar´ e permitir você reconectar. O Ping é apenas para saber se a rede está ativa e evitar uma tentativa desnecessária.


Sanses
   - 12 fev 2006

Oi Aroldo

é o seguinte, entendi sua resposta, mas não consegui por em pratica. No click de um botão coloquei o código seguinte:

#Código


begin
if ping(´10.0.0.10´) then
begin
if IBDatabase1.TestConnected then
begin
IBDatabase1.Connected := true;
IBDatabase1.Open;
end
else
begin
IBDatabase1.CloseDataSets;
IBDatabase1.ForceClose;
IBDatabase1.Connected := false;
end;
end;
end;


Para testar, fiz o seguinte, liguei uma query a uma tabela, coloquei um dbgrid, quando abro a aplicação os dados são mostrados. Logo em seguida eu paro o serviço do Firebird(tudo na maquina local, não tenho rede pra testar) clico neste botão de novo, o ping até passa, mas o testConnected não, e os dados são retirados do meu dbgrid. Perfeito até aqui. Depois eu starto o firebird novamente, clico neste mesmo botão e em seguida clico em outro que chama minha query a exibir os dados no dbgrid (query.open), ai vem o primeiro erro:

´Unable to complete network request to host ´10.0.0.10´.
Error reading data from the connection.
foi forçado o cancelamento de uma conexão existente pelo host remoto

Em seguida clico novamente no botão de teste (o que tem o ping) e depois tento abrir a query novamente, ai da erro:

Dataset open.

Depois disto clico novamente no botão de teste e chamo a query. A partir daqui funciona, ou seja a reconexão esta refeita. O único problema são os dois primeiros erros. Sabe como posso contornar isso ?

Obrigado pela atenção
Sanses


Aroldo Zanela
   - 12 fev 2006

Colega,

Você terá que encher de try...excepts em sua aplicação para esconder os erros. Isso para edições limitadas do Delphi (Professional) e modelo Client/Server, pois existem soluções mais robustas para edições Enterprise e Architect para modelos n-tier.

#Código


if Ping(EnderecoIP) then
begin

try
try
dmERP.dbERP.TestConnected;
dmERP.dbERP.Connected:= false;
dmERP.dbERP.Connected:= true;
except
end;

if dmERP.dbERP.Connected then
begin
try



Fábio Colombo
   - 25 nov 2007

Sanses / Aroldo Zanela

Estou com a mesma dificuldade e já estava tentando seguindo a linha de raciocínio de vocês...
Mesmo aproveitando as dicas de vocês não obtive sucesso...

O que percebí, é que se utilizo o banco de dados e em seguida o fecho... Ao reestabelecer a coneção com o servidor o banco de dados reabre corretamente.

Mas, quando o banco está aberto na hora da perda de conexão com o servidor, aí na tentativa de reconexão com o Banco de Dados, aparecem os erros citados pelo Sanses...

Por enquanto utilizo a desconexão do banco depois de utilizado qualquer procedimento de consulta ou atualização... Isso só funciona bem, pois neste programa o acesso aos dados é muito pequeno, mas, em programas maiores é um problema...


Alguém conseguiu algo que resolva o problema....

Agradeço desde já a atenção....

Abraços
Fábio


Sremulador
   - 26 nov 2007

Realmente amigos isto e um calo nosso, eu já tentei de diversas maneira retirar este erro, quando e no windows 9x e pior ainda, fica aquela linha com erro pra fechar


Marcosrocha
   - 29 nov 2007

Estou usando o código mostrado por vocês e já tentei de diversas maneiras resolver um problema que ainda me assobra.
Eu trabalho que ´Non-Chached´ queries, logo sempre que preciso de um dado, passo a SQL pra query e dou um Open e pego os resultados com FieldByName.
A reconexão com a Base de Dados é feita com sucesso mas quando vou dar um Open da query novamente dá o erro ´Dataset Open´.
O que poderia ser isso? Como resolver?
Obs.: Utilizo IBDatabase + IBQuery (E tem que ser esses dois ok?)


Marcosrocha
   - 17 jan 2008

Amigos. Estou tentando fazer com que meu software reconecte no Banco de Dados utilizando Delphi + Firebird + IBX. A reconexão eu consigo fazer com sucesso mas quando mando abrir uma IBQuery que já continha dados de um select antes da queda, eu obtenho um erro de ´Dataset Open´.
Curiosamente, utilizando este método + MS SQL Server, utilizando as funções CoUninitialize e CoInitialize(nil) (Funções essas do ActiveX) eu consigo reabrir uma Query.
Será que ninguém aqui saberia me dizer se existe funções semelhantes a estas do ActiveX para eu trabalhar com IBX + InterBase|Firebird?

Obs.: os procedimentos sugeridos no tópico http://forum.devmedia.com.br/viewtopic.php?t=73794&highlight= não resolveram meu problema.


Aroldo Zanela
   - 17 jan 2008

Colega,

No Windows98 realmente não deve funcionar em face as restrições do próprio sistema operacional. Nas famílias 2000> e XP pro deve funcionar corretamente.
Qual é o sistema operacional? Pode passar mais detalhes da sua configuração.


Marcosrocha
   - 17 jan 2008

SERVIDOR
Servidor Linux Mandriva
Firebird 1.5.3-pt-br

ESTAÇÕES
Windows XP Service Pack 2
gds32.dll

Fiz um projeto de exemplo utilizando o Employee.fdb da seguinte forma:
Criei um DM com IBDatabase, IBTransaction, IBQuery (InterBase) e um TDatasource (DataAccess).
Na ação de 1 botão eu dou um Open na Query que mostra os dados do select na tabela ´Country´ em um DBGrid.
Vou no Firebird Guard e paro o Serviço (neste momento eu tento refazer a conexão)
Reinicio o Serviço.
Depois de segundos minha aplicação responde à reconexão, consigo inclusive saber novamente quantos usuários estão online com o IBDatabaseInfo mas quando vou dar Open na query para mostrar os dados no DBGrid novamente:
[URL=http://img182.imageshack.us/my.php?image=datasetopenok6.jpg][img:eeb9c4627a]http://img182.imageshack.us/img182/6946/datasetopenok6.th.jpg[/img:eeb9c4627a][/URL]


Carloscavalcanti
   - 07 mar 2009

Estou enfrentando este problema atualmente, alguem sabe como resolve-lo?


Marcosrocha
   - 07 mar 2009

Carlos o problema é o seguinte. É um problema da API do IB que a Borland desenvolveu, no Delphi 2007-2009 o problema de perda de conexão não ocorre mais. No meu caso utilizo Delphi7 então quando a conexão com o Banco de Dados é perdida, eu termino a aplicação via processo. Mesmo porque se a rede do cliente for Física, não há motivos para que ela caia toda hora a menos que esteja com problemas, mas nesse caso não é problema do software.


Mário Filho
   - 11 mar 2015

Eu fiz assim:
1º criei uma fução no datamodule para usar em diversos lugares:
Declare a função lá em cima no seu DM...
...
function testar_conexao(): boolean;
private
public
end;

Depois crie-a lá em baixo clicando simultaneamente na teclas Shift+Alt+C
Ele vai criar algo assim por aí....

function TDm.testar_conexao: boolean;
begin
result:=true;
try
dm.NOMEDOSEUBANCODEDADOS.Connected:=false;
dm.NOMEDOSEUBANCODEDADOS.Connected:=true;
except
result:=false;
end;
end;

Depois onde vou gravar faço a seguinte chamda:

try
dm.NOMEDOSEUBANCODEDADOS.TestConnected;

//Veja, se ele falhar no teste, chamamos a função para corrigir o problema

except
if not dm.testar_conexao() then
begin
// Bom, dentro da função vc viu que desconetamos o banco de dados e tentamos conectá-lo novamente. Se não conseguir a função resulta falso e aí dá a mensagem abaixo, pois provavelmente é um problema físico da rede e não uma simples perda de conexão com o banco de dados!

showmessage('Erro de conexão com o Banco de dados! Saia e entre novamente no sistema.'+#13+
'Se o problema persistir, contacte o Setor de T.I.');
abort;
end;
end;

Espero ter ajudado! Boa sorte.

Lucas Cava
   - 21 abr 2016

Mesmo que faça muito tempo segue a solução que encontrei.

Criei um Timer e a cada X segundos que cada um pode escolher, executar o seguinte código:

#Código

if not FIBConexao.TestConnected then
    FIBConexao.Open;