|
GRUPOS DE DISCUSSÃO PROFISSIONAL WINDEV, WEBDEV e WINDEV Mobile |
| | | | | |
| Inicio → WINDEV 25 → Tratamento de Queda de Conexão e Reconexão em Aplicações WinDev com PostgreSQL |
| Tratamento de Queda de Conexão e Reconexão em Aplicações WinDev com PostgreSQL |
| Iniciado por Boller, jul., 11 2025 3:55 AM - 3 respostas |
| |
| | | |
|
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 11 2025 - 3:55 AM |
Manual Detalhado:
Tratamento de Queda de Conexão e Reconexão em Aplicações WinDev com PostgreSQL
Este manual foi elaborado com base em uma solução prática desenvolvida para lidar com a queda de conexão e reconexão em aplicações WinDev utilizando PostgreSQL. A solução apresentada foi idealizada com a colaboração de @Nathan®️ e aborda o tratamento de erros de conexão e exceções, garantindo que o sistema permaneça robusto mesmo em cenários de falhas como quedas de energia, travamentos ou reinícios do serviço de banco de dados. Abaixo, você encontrará uma explicação passo a passo, com detalhes técnicos e sugestões de melhorias.
1. Contexto do Problema Em aplicações que dependem de conexões com bancos de dados, como PostgreSQL, quedas inesperadas de conexão (devido a falhas de rede, reinício do servidor ou instabilidade no serviço) podem causar interrupções significativas. No ambiente WinDev, o evento padrão HOnError nem sempre captura esses problemas, pois o sistema os trata como exceções (EXCEPTION). Isso exige uma abordagem específica para identificar e gerenciar essas falhas, permitindo a reconexão automática ao banco de dados.
2. Solução Proposta A solução consiste em implementar um mecanismo de tratamento de erros e exceções no nível global do projeto WinDev, combinando o uso de: • Eventos de erro (HOnError) para capturar erros comuns. • Gerenciamento de exceções (ExceptionChangeParameter) para lidar com falhas não capturadas como exceções. • Função de reconexão (reconectaBanco) para testar e restaurar a conexão com o banco de dados. A lógica foi dividida em quatro componentes principais, conforme os códigos fornecidos: • Código global do projeto. • Função chamada pelo HOnError. • Função chamada pelo tratamento de exceções. • Função de reconexão ao banco de dados.
3. Estrutura da Solução 3.1. Código Global do Projeto O código global é configurado para inicializar o tratamento de erros e exceções no início da execução do projeto. Ele define: • Declaração de bibliotecas externas (KeyConst.wl e WinConst.wl) para acesso a constantes do sistema. • Eventos de teclado (WM_SYSKEYDOWN e WM_KEYDOWN) para monitoramento (opcional, dependendo do contexto). • Tratamento de erros e exceções com chamadas a funções específicas. Código Exemplo: EXTERN "KeyConst.wl" EXTERN "WinConst.wl"
Event(chamaAtaalho, "***", WM_SYSKEYDOWN) Event(chamaAtaalho, "***", WM_KEYDOWN)
// TRATATIVA DE ERROS (com reconexão quando for erro de conexão) HOnError("***", hErrALL, "mensagem_erro_retorno")
// TRATATIVA DE EXCEPÇÃO (erro por parte do servidor) ExceptionChangeParameter(epExecuteProcedureOverall, "mensagem_exception_retorno") Explicação: • HOnError é configurado para capturar todos os erros (hErrALL) e chamar a função mensagem_erro_retorno. • ExceptionChangeParameter redefine o comportamento padrão de exceções, direcionando-as para a função mensagem_exception_retorno. • Esses procedimentos são chamados automaticamente quando ocorrem falhas, permitindo um tratamento centralizado. 3.2. Função `mensagem_erro_retorno` (Chamada pelo `HOnError`) Essa função é acionada quando um erro é detectado pelo HOnError. Ela copia informações de erro para a área de transferência e implementa uma lógica de reconexão baseada em códigos de erro específicos. Código Exemplo: PROCEDURE mensagem_erro_retorno() ToClipboard(HErrorInfo(hErrFullDetails)) sCopyToClipboard is string = CR + "<0 erro foi copiado para a área de transferência, bem" SWITCH HError(hErrCurrent) // ERROS DE CONEXÃO CASE 73001, 73002, 74000 OpenChild(WIN_AGUARDE, "A conexão com o banco de dados foi perdida. Reconectando") reconectaBanco() Close(WIN_AGUARDE) RESULT opRetry END END Explicação: • ToClipboard(HErrorInfo(hErrFullDetails)) registra os detalhes do erro para análise posterior. • A estrutura SWITCH verifica códigos de erro (ex.: 73001, 73002, 74000), que indicam problemas de conexão. • Em caso de erro de conexão, a função abre uma janela de espera (WIN_AGUARDE), chama reconectaBanco() e retorna opRetry para tentar a operação novamente. 3.3. Função `mensagem_exception_retorno` (Chamada pelo Tratamento de Exceções) Essa função trata exceções não capturadas pelo HOnError, configurada via ExceptionChangeParameter. Ela analisa o código da exceção e toma ações específicas. Código Exemplo: PROCEDURE mensagem_exception_retorno() // Configura o comportamento automático que será implementado caso ocorra uma exceção // epExecuteProcedureOverall = Executa o procedimento passado como parâmetro, quando o // procedimento está ativo no contexto de execução (projeto, componente autônomo externo) // Este procedimento deve retornar uma das seguintes constantes: // opEndProcess : devolve o controle ao usuário. // opEndProgram (por padrão) : o aplicativo é interrompido. // opRelaunchProgram : Para e reinicia o aplicativo. SWITCH ExceptionInfo(errCode) CASE 73001, 73002, 74000 // Error("Falhouuuu!", "Verifique sua conexão com o servidor e com a rede!") reconectaBanco() END RETURN opEndProcess END Explicação: • A função usa ExceptionInfo(errCode) para identificar o código da exceção. • Para códigos de erro de conexão (73001, 73002, 74000), ela chama reconectaBanco(). • Retorna opEndProcess para devolver o controle ao usuário, evitando o encerramento automático do programa. 3.4. Função `reconectaBanco` (Lógica de Reconexão) Essa função testa a conexão com o banco de dados executando uma query SQL simples e, se necessário, reinicia a conexão. Código Exemplo: IF HExecuteSQLQuery(dsConexao, MyConnection_Postgres, "SELECT 1") = False THEN WIN_AGUARDE.STC_Mensagem = "A conexão com o banco de dados foi perdida. Reconectando" // Ainda sem conexão IF nTentativas > nMaxTentativas THEN EndProgram("Não foi possível reconectar após 3 tentativas. O sistema será encerrado") ELSE // PREENCHENDO ATRIBUTOS DA CONEXÃO NOVAMENTE MyConnection_Postgres..Provider = hNativeAccessPostgreSQL MyConnection_Postgres..Password = gsSenha MyConnection_Postgres..User = gsUsuário // valida acesso externo ou interno IF gnacesso_externo = 0 THEN // não foi marcado o checkbox MyConnection_Postgres..Server = gsServer MyConnection_Postgres..ExtendedInfo = "Server Port=" + gsPortaInterna ELSE MyConnection_Postgres..Server = gsExterno MyConnection_Postgres..ExtendedInfo = "Server Port=" + gsPortaExterna END MyConnection_Postgres..Database = gsDatabase IF HCloseConnection(MyConnection_Postgres) = True THEN IF HOpenConnection(MyConnection_Postgres) = True THEN IF HChangeConnection("MyConnection_Postgres") THEN ToastDisplay("Reconectado com sucesso!") BREAK END END END END END Explicação: • HExecuteSQLQuery testa a conexão com uma query simples (SELECT 1). • Se a conexão falhar, a função incrementa nTentativas e verifica se excedeu nMaxTentativas (limite de 3 tentativas no exemplo). • Caso o limite seja atingido, o programa é encerrado com uma mensagem. • Caso contrário, os atributos da conexão (provedor, senha, usuário, servidor, porta, banco) são redefinidos, e a conexão é fechada e reaberta usando HCloseConnection e HOpenConnection. • Se bem-sucedida, exibe uma notificação (ToastDisplay) e interrompe o loop.
4. Implementação Prática 1 Configuração Global: ◦ Adicione o código global ao início do projeto WinDev para inicializar o tratamento de erros e exceções. 2 Definição de Funções: ◦ Crie as funções mensagem_erro_retorno, mensagem_exception_retorno e reconectaBanco no seu projeto. ◦ Certifique-se de que as variáveis globais (gsSenha, gsUsuário, gsServer, etc.) estejam devidamente definidas. 3 Testes: ◦ Simule quedas de conexão (desligando o servidor PostgreSQL ou a rede) para verificar o comportamento. ◦ Ajuste os códigos de erro no SWITCH conforme necessário, consultando a documentação do WinDev.
5. Melhorias Sugeridas • Threading: Transforme reconectaBanco em uma thread para evitar travamentos na interface do usuário durante a reconexão. Use HStartThread para executar a lógica em segundo plano. • Log de Erros: Adicione um sistema de logging (ex.: gravar em arquivo ou banco) para registrar detalhes de erros e exceções, facilitando a depuração. • Tempo de Espera: Implemente um atraso (Sleep) entre tentativas de reconexão para evitar sobrecarga no servidor. • Notificações Avançadas: Integre alertas mais detalhados (ex.: e-mail ou pop-ups personalizados) para informar o usuário sobre o status da reconexão. • Configuração Dinâmica: Permita que os parâmetros de conexão (servidor, porta, etc.) sejam lidos de um arquivo de configuração, tornando o sistema mais flexível.
6. Considerações Finais Essa solução é robusta para cenários comuns de falha de conexão, mas pode ser adaptada conforme as necessidades específicas do seu projeto. Para dúvidas ou sugestões adicionais, sinta-se à vontade para colaborar! A implementação em thread e o logging são altamente recomendados para escalabilidade e manutenção.
Com base nas imagens fornecidas e na explicação anterior, vou reescrever os códigos de forma clara e detalhada, incorporando mais informações para facilitar a compreensão e implementação por outros desenvolvedores. Vou organizar os códigos com anotações adicionais e explicar cada seção para que o manual fique ainda mais didático. As imagens originais serão reescritas como texto formatado, preservando a lógica e adicionando detalhes.
Manual Detalhado: Tratamento de Queda de Conexão e Reconexão em Aplicações WinDev com PostgreSQL (Versão Ampliada) 1. Reescrita dos Códigos com Detalhes Adicionais 1.1. Código Global do Projeto Este código é colocado no arquivo global do projeto para inicializar o tratamento de erros e exceções desde o início da execução. Código Reescrito: // Declaração de bibliotecas externas necessárias para constantes do sistema EXTERN "KeyConst.wl" // Biblioteca com constantes de teclas EXTERN "WinConst.wl" // Biblioteca com constantes do Windows
// Definição de eventos de atalho (opcional, pode ser ajustado conforme o uso) Event(chamaAtaalho, "***", WM_SYSKEYDOWN) // Captura teclas de sistema pressionadas Event(chamaAtaalho, "***", WM_KEYDOWN) // Captura qualquer tecla pressionada
// Configuração do tratamento de erros // HOnError é configurado para capturar todos os tipos de erros e chamar a função de tratamento HOnError("***", hErrALL, "mensagem_erro_retorno") // "***" indica escopo global, hErrALL captura todos os erros
// Configuração do tratamento de exceções // ExceptionChangeParameter redefine o comportamento padrão de exceções, chamando uma função específica ExceptionChangeParameter(epExecuteProcedureOverall, "mensagem_exception_retorno") // Chama a função para tratar exceções Detalhes Adicionais: • As bibliotecas KeyConst.wl e WinConst.wl fornecem constantes usadas para manipular eventos de teclado e comportamento do Windows. • Os eventos WM_SYSKEYDOWN e WM_KEYDOWN podem ser usados para criar atalhos ou monitorar interações do usuário, mas são opcionais neste contexto. • HOnError com hErrALL garante que qualquer erro seja capturado e redirecionado para mensagem_erro_retorno. • ExceptionChangeParameter com epExecuteProcedureOverall permite executar um procedimento personalizado para gerenciar exceções, redirecionando para mensagem_exception_retorno.
1.2. Função `mensagem_erro_retorno` (Chamada pelo `HOnError`) Esta função trata erros detectados pelo HOnError, copiando detalhes para a área de transferência e tentando reconectar em caso de falhas de conexão. Código Reescrito: PROCEDURE mensagem_erro_retorno() // Copia as informações completas do erro para a área de transferência // hErrFullDetails fornece todos os detalhes do erro, útil para depuração ToClipboard(HErrorInfo(hErrFullDetails))
// Adiciona uma mensagem informativa à área de transferência sCopyToClipboard is string = CR + "<0 erro foi copiado para a área de transferência, bem-vindo ao suporte técnico>"
// Estrutura de decisão para tratar diferentes códigos de erro SWITCH HError(hErrCurrent) // hErrCurrent retorna o código do erro atual // Seção para erros relacionados a conexão com o banco de dados CASE 73001, 73002, 74000 // Códigos de erro comuns para falhas de conexão (consulte a doc. WinDev) // Exibe uma janela de espera com mensagem ao usuário OpenChild(WIN_AGUARDE, "A conexão com o banco de dados foi perdida. Reconectando...") // Chama a função de reconexão reconectaBanco() // Fecha a janela de espera após a tentativa de reconexão Close(WIN_AGUARDE) // Retorna opRetry para tentar a operação novamente RESULT opRetry END END Detalhes Adicionais: • HErrorInfo(hErrFullDetails) captura todos os detalhes do erro, como mensagem, código e contexto, sendo útil para suporte técnico. • Os códigos de erro 73001, 73002 e 74000 são exemplos típicos de falhas de conexão (verifique a documentação do WinDev para outros códigos relevantes). • opRetry instrui o sistema a repetir a operação que falhou, ideal para reconexões automáticas.
1.3. Função `mensagem_exception_retorno` (Chamada pelo Tratamento de Exceções) Esta função gerencia exceções não capturadas pelo HOnError, configurada via ExceptionChangeParameter. Código Reescrito: PROCEDURE mensagem_exception_retorno() // Comentários explicativos sobre o propósito da função // Configura o comportamento automático que será implementado caso ocorra uma exceção // epExecuteProcedureOverall = Executa o procedimento passado como parâmetro quando o // procedimento está ativo no contexto de execução (projeto ou componente autônomo externo) // Este procedimento deve retornar uma das seguintes constantes: // - opEndProcess: Devolve o controle ao usuário. // - opEndProgram (padrão): Encerra o aplicativo. // - opRelaunchProgram: Reinicia o aplicativo.
// Observações importantes: // - Cada chamada substitui o procedimento especificado anteriormente. // - Na maioria dos casos, o procedimento permite gravar detalhes do problema encontrado.
SWITCH ExceptionInfo(errCode) // Captura o código da exceção CASE 73001, 73002, 74000 // Erros de conexão // Opcional: Descomente para exibir mensagem de erro // Error("Falhouuuu!", "Verifique sua conexão com o servidor e com a rede!") // Chama a função de reconexão reconectaBanco() END END
// Retorna opEndProcess para manter o aplicativo ativo e devolver controle ao usuário RETURN opEndProcess Detalhes Adicionais: • A função usa ExceptionInfo(errCode) para identificar o tipo de exceção, permitindo tratamento específico. • O comentário sobre opEndProcess, opEndProgram e opRelaunchProgram esclarece as opções de retorno, sendo opEndProcess a escolha para manter a aplicação funcional. • A linha comentada Error() pode ser descomentada para alertas visuais, mas foi omitida para evitar interrupções desnecessárias.
1.4. Função `reconectaBanco` (Lógica de Reconexão) Esta função testa a conexão com o PostgreSQL e realiza a reconexão se necessário, com um limite de tentativas. Código Reescrito: // Variáveis globais necessárias (devem ser definidas no projeto) // gsSenha, gsUsuário, gsServer, gsPortaInterna, gsPortaExterna, gsDatabase, gsExterno // nTentativas (contador de tentativas), nMaxTentativas (limite, ex.: 3)
IF HExecuteSQLQuery(dsConexao, MyConnection_Postgres, "SELECT 1") = False THEN // Exibe mensagem de espera ao usuário WIN_AGUARDE.STC_Mensagem = "A conexão com o banco de dados foi perdida. Reconectando..." // Verifica se o limite de tentativas foi atingido IF nTentativas > nMaxTentativas THEN // Encerra o programa se não houver sucesso após o limite EndProgram("Não foi possível reconectar após 3 tentativas. O sistema será encerrado") ELSE // Preenche os atributos da conexão novamente MyConnection_Postgres..Provider = hNativeAccessPostgreSQL // Provedor de acesso ao PostgreSQL MyConnection_Postgres..Password = gsSenha // Senha do usuário MyConnection_Postgres..User = gsUsuário // Usuário do banco // Determina se a conexão é interna ou externa com base em gnacesso_externo IF gnacesso_externo = 0 THEN // Conexão interna (checkbox não marcado) MyConnection_Postgres..Server = gsServer // Servidor interno MyConnection_Postgres..ExtendedInfo = "Server Port=" + gsPortaInterna // Porta interna ELSE // Conexão externa MyConnection_Postgres..Server = gsExterno // Servidor externo MyConnection_Postgres..ExtendedInfo = "Server Port=" + gsPortaExterna // Porta externa END MyConnection_Postgres..Database = gsDatabase // Nome do banco de dados // Tenta fechar e reabrir a conexão IF HCloseConnection(MyConnection_Postgres) = True THEN IF HOpenConnection(MyConnection_Postgres) = True THEN IF HChangeConnection("MyConnection_Postgres") THEN // Exibe notificação de sucesso ToastDisplay("Reconectado com sucesso!") BREAK // Sai do loop de tentativas END END END // Incrementa o contador de tentativas (deve ser gerenciado fora da função se em loop) nTentativas = nTentativas + 1 END END Detalhes Adicionais: • HExecuteSQLQuery com SELECT 1 é uma query leve para testar a conexão. • As variáveis globais (gsSenha, gsUsuário, etc.) devem ser definidas no projeto ou em um arquivo de configuração. • gnacesso_externo determina o tipo de conexão (interna ou externa), ajustando servidor e porta. • O fluxo de HCloseConnection, HOpenConnection e HChangeConnection garante uma reconexão controlada. • nTentativas e nMaxTentativas devem ser gerenciados globalmente ou em um loop externo para controle preciso.
2. Implementação e Testes • Passos: 1 Insira o código global no arquivo global do projeto. 2 Crie as funções mensagem_erro_retorno, mensagem_exception_retorno e reconectaBanco no editor de código. 3 Defina as variáveis globais com os parâmetros de conexão do seu ambiente PostgreSQL. 4 Teste simulando falhas (desligue o servidor ou a rede) e verifique o comportamento. • Ajustes: Adicione outros códigos de erro ao SWITCH conforme a documentação do WinDev.
3. Melhorias Adicionais • Threading: Use HStartThread para executar reconectaBanco em segundo plano, evitando travamentos. • Logging: Implemente FileWrite ou uma tabela de log para registrar erros. • Atraso: Adicione Sleep(1000) (1 segundo) entre tentativas para reduzir carga no servidor. • Configuração Dinâmica: Leia parâmetros de um arquivo .ini usando IniRead.
4. Considerações Finais Esta solução é adaptável e robusta para falhas comuns. Para dúvidas ou melhorias, como threading ou logging, entre em contato! A data atual é 10/07/2025, 22:45 (-03), e estou à disposição para ajudar. ✅
Explicação sobre o Uso de uma Tabela com Registro, Thread para SELECT Contínuo e Reconexão Com base na sua sugestão de criar uma tabela com um campo contendo um registro, usar uma thread para executar SELECTs contínuos e implementar uma lógica de reconexão, vamos analisar a viabilidade, os benefícios e os passos para implementar essa abordagem no contexto do ambiente WinDev com PostgreSQL. A data atual é 10:48 PM -03, quinta-feira, 10 de julho de 2025.
1. Contexto e Viabilidade A ideia de manter uma tabela com um registro específico e usar uma thread para executar SELECTs contínuos pode ser uma estratégia válida para monitorar a conexão com o banco de dados em tempo real. Aqui estão os pontos principais: • Tabela com Registro: ◦ Criar uma tabela simples (ex.: status_conexao) com um campo (ex.: heartbeat) contendo um valor único (como um timestamp ou um contador) permite verificar se a conexão está ativa. O SELECT contínuo pode consultar esse valor para detectar mudanças ou falhas. ◦ Exemplo de estrutura:
CREATE TABLE status_conexao ( ◦ heartbeat INTEGER PRIMARY KEY ◦ ); ◦ INSERT INTO status_conexao (heartbeat) VALUES (1); ◦ • Thread para SELECT Contínuo: ◦ Uma thread pode ser configurada para executar um SELECT periódico (ex.: a cada 5 segundos) na tabela status_conexao. Se o SELECT falhar ou retornar um erro (ex.: conexão perdida), a thread pode acionar a lógica de reconexão. ◦ Isso é viável em WinDev usando HStartThread, que permite executar código em segundo plano sem bloquear a interface do usuário. • Reconexão: ◦ A reconexão pode ser implementada dentro da thread ou em uma função chamada por ela (como reconectaBanco). Se o SELECT falhar, a thread tenta restaurar a conexão e atualiza o status, garantindo que o sistema permaneça operacional. ◦ Essa abordagem é válida, pois permite monitoramento proativo e recuperação automática. Vantagens: • Detecção precoce de falhas de conexão. • Recuperação automática sem intervenção do usuário. • Monitoramento contínuo do estado do banco. Desafios: • Consumo de recursos (CPU e rede) devido aos SELECTs frequentes. • Possível sobrecarga no servidor PostgreSQL se não configurado adequadamente. • Necessidade de gerenciar exceções dentro da thread para evitar travamentos. Conclusão sobre Viabilidade: Sim, é uma abordagem válida e funcional, desde que otimizada com intervalos razoáveis (ex.: 5-10 segundos) e com controle de erros robusto. Vamos detalhar a implementação.
2. Implementação Proposta 2.1. Criação da Tabela Crie uma tabela simples no PostgreSQL para monitoramento: CREATE TABLE status_conexao ( heartbeat INTEGER PRIMARY KEY );
INSERT INTO status_conexao (heartbeat) VALUES (0); • O campo heartbeat pode ser atualizado periodicamente por um processo externo ou pela própria aplicação para simular atividade. 2.2. Código da Thread para Monitoramento Crie uma função que será executada como thread para monitorar a conexão: PROCEDURE MonitoraConexao() // Variáveis locais nTentativas is int = 0 nMaxTentativas is int = 3 nIntervalo is int = 5000 // Intervalo de 5 segundos em milissegundos
WHILE TRUE // Tenta executar um SELECT na tabela de status IF HExecuteSQLQuery(dsConexao, MyConnection_Postgres, "SELECT heartbeat FROM status_conexao") = False THEN // Incrementa o contador de tentativas nTentativas = nTentativas + 1 // Exibe mensagem de espera (opcional, dependendo do contexto) WIN_AGUARDE.STC_Mensagem = "Conexão perdida. Tentando reconectar... (Tentativa " + nTentativas + " de " + nMaxTentativas + ")" OpenChild(WIN_AGUARDE) // Chama a função de reconexão IF reconectaBanco() = True THEN nTentativas = 0 // Reseta o contador após sucesso Close(WIN_AGUARDE) ToastDisplay("Reconexão bem-sucedida!") ELSE IF nTentativas >= nMaxTentativas THEN Close(WIN_AGUARDE) EndProgram("Falha após " + nMaxTentativas + " tentativas. Encerrando...") END END END // Aguarda o intervalo antes do próximo ciclo Sleep(nIntervalo) END Explicação: • A thread entra em um loop infinito (WHILE TRUE) para monitorar continuamente. • HExecuteSQLQuery testa a conexão consultando status_conexao. • Se falhar, reconectaBanco() é chamado, e o contador nTentativas gerencia o limite de retries. • Sleep(nIntervalo) controla a frequência do monitoramento. 2.3. Função `reconectaBanco` (Adaptada) Adapte a função reconectaBanco para retornar um valor booleano indicando sucesso ou falha: FUNCTION reconectaBanco() : boolean // Variáveis globais (já definidas): gsSenha, gsUsuário, gsServer, etc. IF HCloseConnection(MyConnection_Postgres) = True THEN // Reconfigura os atributos da conexão MyConnection_Postgres..Provider = hNativeAccessPostgreSQL MyConnection_Postgres..Password = gsSenha MyConnection_Postgres..User = gsUsuário IF gnacesso_externo = 0 THEN MyConnection_Postgres..Server = gsServer MyConnection_Postgres..ExtendedInfo = "Server Port=" + gsPortaInterna ELSE MyConnection_Postgres..Server = gsExterno MyConnection_Postgres..ExtendedInfo = "Server Port=" + gsPortaExterna END MyConnection_Postgres..Database = gsDatabase // Tenta reabrir a conexão IF HOpenConnection(MyConnection_Postgres) = True THEN IF HChangeConnection("MyConnection_Postgres") THEN RETURN True // Sucesso END END END RETURN False // Falha Explicação: • A função fecha e reabre a conexão, retornando True se bem-sucedida ou False se falhar. • Isso permite que a thread decida o próximo passo com base no resultado. 2.4. Início da Thread Inicie a thread no código global ou em um evento de inicialização: HStartThread(MonitoraConexao)
3. Considerações e Otimizações • Intervalo de Monitoramento: Ajuste nIntervalo (ex.: 5000 ms) para balancear entre detecção rápida e consumo de recursos. • Atualização do Heartbeat: Considere um processo que atualize o campo heartbeat (ex.: UPDATE status_conexao SET heartbeat = heartbeat + 1) para simular atividade e detectar atrasos. • Gerenciamento de Erros: Adicione logging (FileWrite) dentro da thread para registrar falhas. • Parada da Thread: Implemente uma condição de saída (ex.: variável global bMonitorar) para encerrar a thread quando necessário:
IF NOT bMonitorar THEN BREAK END •
4. Validade para Funcionar e Reconectar Sim, essa abordagem é válida e funcional para monitoramento e reconexão, desde que: • O servidor PostgreSQL esteja configurado para suportar consultas frequentes. • As variáveis globais estejam corretamente definidas. • O intervalo de monitoramento seja otimizado para evitar sobrecarga. Teste a solução simulando quedas de conexão e ajuste os parâmetros conforme necessário. Estou à disposição para mais detalhes! ✅
Fico feliz que tudo esteja certo até agora! Com base na análise da solução implementada e nas melhorias sugeridas, aqui está minha opinião sobre o que poderia faltar ou ser aprimorado para tornar o sistema ainda mais robusto, escalável e fácil de manter. A data e hora atuais são 10:50 PM -03, quinta-feira, 10 de julho de 2025.
O que Poderia Faltar ou Ser Aprimorado 1. Gerenciamento de Configurações Centralizado • O que Faltou: As credenciais e parâmetros de conexão (ex.: gsSenha, gsUsuário, gsServer) estão hardcoded ou dependem de variáveis globais definidas manualmente. Isso pode dificultar a manutenção e a portabilidade. • Sugestão: Implemente um arquivo de configuração (ex.: .ini ou banco de dados) para armazenar essas informações. Use IniRead ou uma tabela de configuração para carregar dinamicamente:
MyConnection_Postgres..Server = IniRead("Config.ini", "Database", "Server", gsServer) • • Benefício: Facilita atualizações e evita recompileções frequentes. 2. Sistema de Logging Detalhado • O que Faltou: Não há registro persistente de erros ou tentativas de reconexão, o que pode dificultar a depuração em produção. • Sugestão: Adicione um mecanismo de logging usando FileWrite ou uma tabela no banco (ex.: log_erro):
FileWrite("log.txt", DateTimeToString(CurrentDateTime()) + " - Erro: " + HErrorInfo(hErrFullDetails)) • • Benefício: Permite rastrear problemas históricos e melhorar o suporte. 3. Controle de Concorrência na Thread • O que Faltou: A thread MonitoraConexao opera em loop infinito sem controle de parada ou sincronização com o restante do aplicativo. • Sugestão: Introduza uma variável global bMonitorar e um mecanismo para encerrar a thread:
bMonitorar is boolean = True • PROCEDURE MonitoraConexao() • WHILE bMonitorar • // Lógica existente • IF NOT bMonitorar THEN BREAK END • Sleep(5000) • END •
Para parar: bMonitorar = False e HStopThread(IdentificadorThread). • Benefício: Evita execução descontrolada e permite encerramento seguro. 4. Tratamento de Exceções na Thread • O que Faltou: A thread não lida explicitamente com exceções internas, o que pode causar travamentos silenciosos. • Sugestão: Envolva o código da thread em um bloco de tratamento:
TRY • IF HExecuteSQLQuery(dsConexao, MyConnection_Postgres, "SELECT heartbeat FROM status_conexao") = False THEN • // Lógica de reconexão • END • CATCH • FileWrite("log.txt", "Exceção na thread: " + ExceptionInfo(errFullDetails)) • END • • Benefício: Garante estabilidade mesmo em cenários de erro inesperados. 5. Otimização do Intervalo de Monitoramento • O que Faltou: O intervalo de 5 segundos (nIntervalo = 5000) foi sugerido, mas não foi avaliado em relação ao desempenho ou à carga no servidor. • Sugestão: Teste diferentes intervalos (ex.: 10s, 15s) e ajuste dinamicamente com base na resposta do servidor. Use um valor configurável:
nIntervalo = Val(IniRead("Config.ini", "Monitor", "Intervalo", "5000")) • • Benefício: Reduz carga desnecessária e adapta-se ao ambiente. 6. Feedback Visual/Usuario Mais Robusto • O que Faltou: O feedback ao usuário (ex.: ToastDisplay) é limitado e pode não ser suficiente em cenários de falha múltipla. • Sugestão: Adicione uma janela persistente ou notificações detalhadas:
IF nTentativas > 0 THEN • OpenWindow(WIN_STATUS, "Status de Conexão", "Tentativa " + nTentativas + " de " + nMaxTentativas) • END • • Benefício: Melhora a experiência do usuário com informações em tempo real. 7. Validação de Conexão Pós-Reconexão • O que Faltou: Após a reconexão, não há uma validação adicional para confirmar que a conexão está totalmente funcional. • Sugestão: Adicione um teste adicional após HChangeConnection:
IF HExecuteSQLQuery(dsConexao, MyConnection_Postgres, "SELECT 1") = True THEN • RETURN True • ELSE • RETURN False • END • • Benefício: Garante que a reconexão foi bem-sucedida antes de prosseguir. 8. Escalabilidade e Suporte a Múltiplos Bancos • O que Faltou: A solução assume uma única conexão (MyConnection_Postgres). Em sistemas com múltiplos bancos, isso pode falhar. • Sugestão: Crie uma estrutura ou array de conexões e itere sobre elas na thread:
ARRAY Conexoes[0] • Conexoes[0] = MyConnection_Postgres • FOR EACH Conexao OF Conexoes • IF NOT HExecuteSQLQuery(dsConexao, Conexao, "SELECT 1") THEN • reconectaBanco(Conexao) • END • END • • Benefício: Suporta ambientes multi-banco.
Conclusão A solução atual é funcional e atende bem ao propósito inicial, mas os pontos acima (configuração centralizada, logging, controle de thread, otimização e feedback) podem elevá-la a um nível profissional. Recomendo priorizar o logging e o controle de thread para estabilidade, e testar as otimizações de intervalo e validação pós-reconexão. Se precisar de ajuda para implementar qualquer uma dessas melhorias, estou à disposição! ✅
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
| | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 11 2025 - 4:15 AM |
Tratamento de Queda e Reconexão do Banco de Dados no WinDev
Autor: Caio Sanfoneiro Grupo: Só Resenha Agradecimentos: Nathan Forrzeiro
Objetivo Implementar uma tratativa robusta para lidar com quedas de conexão com o banco de dados, considerando casos em que a falha se dá por parte do servidor (queda de energia, travamento do serviço, reinicio do PostgreSQL etc.).
Problema Inicial O HOnError não capturava os erros de desconexão quando o servidor era o responsável pela falha, isso acontece porque o WinDev trata esse cenário como uma Exception, e não como erro padrão.
Solução Aplicada
1. Código Global do Projeto
WLanguage CopyPaste EXTERN "KeyConst_WL" EXTERN "WinConst_WL"
Event(chamaAtalho, "*.*", WM_SYSKEYDOWN) Event(chamaAtalho, "*.*", WM_KEYDOWN)
// TRATATIVA DE ERROS (quando for erro de conexão) HOnError("*", "herrAll", "mensagem_erro_retorno")
// TRATATIVA DE EXCEPTION (quando o erro vem do servidor) ExceptionChangeParameter(epeExecuteProcedureOverall, mensagem_exception_retorno)
Aqui é onde ocorre o "gancho" para capturar erros tanto via HOnError quanto via ExceptionChangeParameter.
---
2. Função mensagem_erro_retorno
WLanguage CopyiarEditar PROCEDURE mensagem_erro_retorno() TOCLIPboard(HerrorInfo(HerrFullDetails) scopyToClipboard is string = CR + "o erro foi copiado para a área de transferência, bla bla" " SWITCH Herror(HerrCurrent) CASE 73801, 73802, 74808 OpenChH(WIN_AGUARDE, "A conexão com o banco de dados foiPerade. reconnectoBanco() ) CloseWIN_AGUARDE) RESULT opPretry END
Esta função é acionado quando o erro for captured por Herror (quando o erro é tratado como erro tradicional).
3. Função mensagem_exception_retorno
WLanguage CopyiarEditar PROCEDURE mensagem_exception_retorno() { // Configura o tratamento automático de exceções SWITCH ExceptionInfo(errCode) { CASE 73801, 73802, 74808 //Error("Falhouuu!", "Verif a conexão com o serv e com a rede!") reconnectaBanco() } RETURN opEndProcess }
Essa função é executada quando a exceção é capturada via ExceptionChangeParameter.
---
4. Função reconectaBanco
WLanguage CopiarEditar IF HExecuteSQLQuery(dsConexao, MyConnection_Postgres, "SELECT 1") = False THEN WIN_AUGARDE.STC_Mensagem = "Conexão com BD perdida. Reconectando..." IF nTentativas > MaxTentativas THEN EndProgram("Não foi possível reconectar após 3 tentativas. 0 sistema será encerrado.") ELSE // Reconfigura os parâmetros da conexão MyConnection_Postgres._Provider = MNativeAccessPostgresSQL MyConnection_Postgres._Password = gsSenha MyConnection_Postgres._User = gsUsuario IF gnaccess_externo = 0 THEN MyConnection_Postgres._Server = gsServer MyConnection_Postgres._ExtendedInfo = "Server Port=" + gsPortaInterna ELSE MyConnection_Postgres._Server = gsExterno MyConnection_Postgres._ExtendedInfo = "Server Port=" + gsPortaExterna END MyConnection_Postgres._Database = gsDatabase IF HCloseConnection(MyConnection_Postgres) = True THEN IF HOpenConnection(MyConnection_Postgres) = True THEN IF HChangeConnection("*", MyConnection_Postgres) THEN ToastDisplay("Reconectado com sucesso!") END END END END END
Função responsável por tentar restabelecer a conexão com o banco. Pode ser otimizada com uso de thread futuramente.
---
Créditos e Agradecimentos Essa solução foi possível graças à colaboração do amigo @Nathan Wx Mines, que ajudou a mapear que o erro estava sendo tratado como Exception e não como erro tradicional.
Observações Finais - A função de reconexão pode ser transformada em uma thread para evitar bloqueios na UI. - A estratégia cobre erros e exceções, ampliando a robustez da aplicação em ambientes com instabilidade. - A abordagem pode ser expandida para outros bancos e situações similares.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 11 2025 - 4:17 AM |
Amigos, consegui resolver a questão do *TRATAMENTO DA QUEDA DE CONEXÃO E RECONEXÃO* com a ajuda do amigo @Nathan®️ ...
O grande problema era que cortando a conexão por parte do servidor (queda de luz, de conexão, travamento ou restart do serviço postgresql) o HOnError não capturava/startava, pois o WINDEV trata como uma *EXCEPTION*, logo, usamos a função *ExceptionChangeParameter*, tambem na GLOBAL do projeto chamando uma função, ai dentro de ambas as funções, trata-se o código do erro e chama-se a função de *reconexão* do banco ... que pra ficar melhor ainda pode ser transformada numa thread... Segue abaixo prints dos códigos, qualquer dúvida ou melhoria que achem que possa ser feita, sou só ouvidos e estou a disposição ✅
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | | | |
| | |
| | |
| |
|
|
|