Eu tenho um aplicativo que escrevi que usa OCI para se conectar a um banco de dados Oracle. O banco de dados foi atualizado recentemente para o Oracle 18 e, desde então, as pesquisas de banco de dados no aplicativo param de funcionar aleatoriamente.
Eu reduzi o problema a isso. Quando o aplicativo se conecta ao banco de dados, ele executa alguns ALTER SESSION
comandos para desabilitar a distinção entre maiúsculas e minúsculas nas LIKE
condições (para que eu possa procurar "smith" e ainda encontrar "Smith"). Após algumas horas, a rede desconecta a conexão TCP. Na manhã seguinte, quando alguém tenta acessar o sistema, o cliente Oracle se reconecta e executa a consulta de forma transparente.
O problema é que essa reconexão acontece sem que meu código saiba disso, aparentemente pelo próprio cliente Oracle, e ele não executa novamente os ALTER SESSION
comandos originais após a reconexão. Nossos DBAs me forneceram um log de auditoria que mostra a alteração do ID da sessão, uma nova LOGON
tentativa e uma única ALTER SESSION
execução para definir o fuso horário (que não vem do meu código e também apareceu na conexão original).
Isso significa que meu aplicativo emite consultas ao banco de dados normalmente, sem saber que houve alguma interrupção, mas de repente elas diferenciam maiúsculas de minúsculas e os usuários começam a reclamar que a pesquisa não está retornando nenhum resultado.
Com a versão anterior do servidor Oracle meu código receberia um erro se tivesse sido desconectado, e o código tentaria se reconectar e como parte da reconexão, ele executaria os ALTER SESSION
comandos novamente para que não houvesse alteração no comportamento do sistema .
Não consigo encontrar nada sobre esse recurso de reconexão automática ou como ajustá-lo, então existe alguma maneira de preservar as ALTER SESSION
alterações para que sejam reaplicadas após a reconexão ou desabilitar esse comportamento e retornar um erro ao código se a conexão for perdida como costumava acontecer?
O cliente é um 11.2 mais antigo e atualizá-lo não é muito prático, mas como funcionava antes da atualização do servidor, eu achava que essa versão seria boa.
Parece que o Transparent Application Failover (TAF) está habilitado para sua conexão. Se o TAF estiver ativado, o cliente Oracle o reconectará ao banco de dados ou a um banco de dados alternativo se a conexão entre o cliente e o servidor for interrompida. Você usa um cliente OCI e para isso é possível registrar uma função de retorno de chamada de failover que é chamada após a reconexão do cliente. Nesta função de retorno de chamada, você pode emitir o comando 'ALTER SESSION' necessário. Mas talvez você não queira usar o TAF.
Portanto, primeiro o DBA deve verificar se sua sessão usa TAF. Uma consulta apropriada pode ser encontrada no Guia do Administrador do Net Services
Com o seguinte exemplo de saída
FAILOVER_TYPE NONE nos diz que nenhum TAF está configurado. FAILOVER_TYPE diferente de NONE nos informa que o TAF está configurado para essas sessões.
Se a sua sessão usa o TAF, você deve descobrir onde está configurado. Pode ser configurado no lado do cliente ou no lado do servidor. Você pode verificar seu arquivo 'tnsname.ora' ou usar seu utilitário 'tnsping' para verificar a configuração do seu cliente. Se você encontrar algo semelhante a este exemplo do Guia do Administrador do Net Services
então o TAF é configurado por causa do
FAILOVER_MODE=(TYPE=select)
. Se este for o caso, você deve configurar uma string de conexão apropriada sem TAF.Mas mesmo que nenhum TAF esteja configurado no lado do cliente, ele pode ser configurado no lado do servidor para este serviço. Então faça a seguinte consulta
A saída de exemplo a seguir mostra que o TAF será usado
(SERVICE_NAME=sales.us.example.com)
mesmo que não esteja configurado no cliente.Nesse caso, o TAF será usado
(SERVICE_NAME=sales.us.example.com)
mesmo que o TAF não esteja configurado no cliente. Portanto, você deve usar um serviço que não tenha o TAF configurado, no exemplo 'sales3.us.example.com' é um serviço desse tipo.O serviço pode ser criado com o pacote DBMS_SERVICE, mas na maioria dos casos eles são criados por algumas ferramentas adicionais como o Oracle Real Application Cluster. Pode-se exibir os serviços criados pelo RAC para um banco de dados 'salesdb' executando o seguinte comando no servidor de banco de dados
A saída a seguir (que depende da versão do banco de dados) mostra que o RAC criará um serviço TAF após o início do banco de dados
você pode criar um novo serviço 'sales3.us.example.com' sem TAF com o seguinte comando
Como solução alternativa, um gatilho foi adicionado à conta do usuário para executar o
ALTER SESSION
comando em cada conexão. Isso corrigiu o problema, mas ainda não temos certeza do motivo pelo qual a sessão se reconecta de forma transparente sem nenhuma notificação ao aplicativo cliente!