Reconectar ao banco FB
11/02/2006
0
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
Sanses
Posts
11/02/2006
Aroldo Zanela
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:
if Ping(EnderecoIP) then begin if dmERP.dbERP.TestConnected then begin
11/02/2006
Sanses
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
11/02/2006
Aroldo Zanela
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.
12/02/2006
Sanses
é o seguinte, entendi sua resposta, mas não consegui por em pratica. No click de um botão coloquei o código seguinte:
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
12/02/2006
Aroldo Zanela
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.
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
25/11/2007
Fábio Colombo
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
26/11/2007
Sremulador
29/11/2007
Marcosrocha
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?)
17/01/2008
Marcosrocha
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.
17/01/2008
Aroldo Zanela
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.
17/01/2008
Marcosrocha
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]
07/03/2009
Carloscavalcanti
07/03/2009
Marcosrocha
11/03/2015
Mário Filho
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.
21/04/2016
Lucas Cava
Criei um Timer e a cada X segundos que cada um pode escolher, executar o seguinte código:
if not FIBConexao.TestConnected then FIBConexao.Open;
Clique aqui para fazer login e interagir na Comunidade :)