Erros e solução de problemas - raialmeida/mindqa-db-commons GitHub Wiki

Erros e solução de problemas

Falhas de conexão, SQL, autenticação e fechamento lançam DatabaseException. Sua mensagem é a mesma do driver, e a SQLException original permanece disponível em getCause() e getSQLException(), incluindo SQLState, código do fornecedor e exceções suprimidas.

IllegalArgumentException indica argumentos inválidos ou valores de configuração fora do formato ou intervalo aceito, como tipo, porta ou tamanho do pool. IllegalStateException indica configuração obrigatória ausente, seleção ambígua, arquivo ilegível ou uma conexão nomeada desconhecida.

Pool de conexões e cache

O pool e o cache são opcionais e permanecem desativados por padrão. A ausência dessas propriedades não é um erro: cada operação abre e fecha sua conexão física e a configuração é relida normalmente.

DB_CONFIG_CACHE_ENABLED=true
DB_POOL_ENABLED=true
DB_POOL_MAX_SIZE=5
DB_POOL_CONNECTION_TIMEOUT_MS=30000

Função de cada variável:

Variável Função
DB_CONFIG_CACHE_ENABLED Reutiliza a configuração carregada, evitando reler o arquivo .properties a cada operação.
DB_POOL_ENABLED Habilita a reutilização de conexões físicas por meio do pool.
DB_POOL_MAX_SIZE Define o número máximo de conexões físicas mantidas no pool.
DB_POOL_CONNECTION_TIMEOUT_MS Define quanto tempo, em milissegundos, uma operação espera por uma conexão disponível.

DB_CONFIG_CACHE_ENABLED é global. As propriedades DB_POOL_* pertencem à configuração simples DB_*. Para uma conexão nomeada, use DB_CONNECTIONS_<NOME>_POOL_*; para uma conexão por tipo, use por exemplo POSTGRESQL_POOL_* ou POSTGRESQL_PRINCIPAL_POOL_*. Mesmo que uma conexão nomeada seja escolhida por DB_DEFAULT_CONNECTION, ela não herda DB_POOL_*. O pool é criado na primeira operação da conexão que o habilitou. Nos logs do HikariCP, o nome segue <conexão>-<base> pool-<número>; a configuração simples usa o motor normalizado como conexão, por exemplo postgresql-qa_database pool-1. O número identifica a instância do pool sem expor credenciais. Caracteres fora de letras, números, ponto, hífen e sublinhado são substituídos por _. Conexões nomeadas, bases, credenciais ou opções diferentes podem gerar pools separados. Há um limite de 32 pools por instância da biblioteca; destinos adicionais usam conexões diretas.

Os logs do HikariCP dependem de uma implementação SLF4J no projeto consumidor, como Logback, Log4j2 com integração SLF4J ou slf4j-simple. Configure o logger com.zaxxer.hikari em INFO para visualizar início e encerramento dos pools, ou em DEBUG para detalhes e estatísticas. A biblioteca não inclui uma implementação de logging; sem ela, o pool continua funcionando, mas seus logs não são exibidos. Se o projeto já possui logging configurado, confira o nível desse logger e a saída de logs habilitada.

Para uma conexão nomeada, aplique o prefixo dela. Por exemplo:

DB_CONNECTIONS_PRINCIPAL_POOL_ENABLED=true
DB_CONNECTIONS_PRINCIPAL_POOL_MAX_SIZE=5
DB_CONNECTIONS_PRINCIPAL_POOL_CONNECTION_TIMEOUT_MS=30000
Situação Causa provável Solução
DatabaseException cuja causa é SQLTransientConnectionException A obtenção de uma conexão pode ter excedido POOL_CONNECTION_TIMEOUT_MS, por ocupação ou falha ao abrir conexões. Confira a causa JDBC e a disponibilidade do banco; em caso de ocupação, ajuste o tamanho, a espera ou o paralelismo.
Conexões ficam abertas depois de uma query Com pool ativo, close() devolve a conexão ao pool para reutilização. É esperado. Chame DatabaseService.closePools() ao encerrar a suíte se quiser liberá-las antes do fim da JVM.
Alteração no .properties não é percebida DB_CONFIG_CACHE_ENABLED=true mantém o snapshot da configuração. Execute DatabaseService.clearConfigurationCache() antes da próxima operação.
Pool não é usado em uma conexão nomeada As chaves foram configuradas apenas como DB_POOL_*. Configure DB_CONNECTIONS_<NOME>_POOL_* para a conexão desejada.
IllegalArgumentException para opções do pool Valor inválido: booleano diferente de true/false, tamanho menor que 1 ou espera menor que 1000. Corrija POOL_ENABLED, POOL_MAX_SIZE ou POOL_CONNECTION_TIMEOUT_MS.

Em uma execução com uma única classe JUnit, este @AfterAll libera os recursos após os testes da classe:

import io.mindqa.database.DatabaseService;
import org.junit.jupiter.api.AfterAll;

@AfterAll
static void finalizarBanco() {
    DatabaseService.closePools();
    DatabaseService.clearConfigurationCache();
}

@AfterAll é executado por classe, não uma vez por suíte. Se várias classes compartilham os pools, use um encerramento global do seu executor após todas terminarem, ou deixe o encerramento normal da JVM fechá-los. Não feche pools enquanto outras classes ainda os utilizam.

Não chame closePools() em @AfterEach se quiser reutilizar conexões entre testes. closePools() fecha todos os pools da instância da biblioteca; uma operação posterior pode criá-los novamente. clearConfigurationCache() apenas descarta as configurações em cache, sem fechar conexões.

Ao fechar um pool, a biblioteca aguarda o LOGIN_TIMEOUT_SECONDS configurado para as tarefas internas de criação de conexão terminarem. Quando o valor é 0, usa cinco segundos apenas nesse encerramento; o timeout padrão do driver permanece inalterado.

O pool restaura estados JDBC usuais, como autoCommit, mas não desfaz comandos SQL que alteram a sessão, como SET, USE ou a criação de tabelas temporárias. Se um teste depender de uma sessão inteiramente nova a cada operação, mantenha DB_POOL_ENABLED=false nessa conexão. Para uma conexão nomeada, use a propriedade correspondente, como DB_CONNECTIONS_PRINCIPAL_POOL_ENABLED=false.

⚠️ **GitHub.com Fallback** ⚠️