Pergunta

No nosso servidor / cliente-setup estamos experimentando algum comportamento estranho. O cliente é um C / C ++ - aplicação que utiliza OCI para se conectar a um servidor Oracle (usando o OTL biblioteca) .

De vez em quando as matrizes de servidor de banco de dados em uma forma (sim esta é a questão central, mas do lado do aplicativo não podemos resolvê-lo, mas tem que lidar com ele de qualquer maneira), que a máquina não responder mais a novos pedidos / conexões, mas os já existentes, como o oráculo-conexões, não deixe cair ou fora do tempo. Consultas enviadas para o DB apenas nunca voltar mais sucesso.

Que possibilidades (se houver) são fornecidos pela Oracle para detectar essas conexões retidas lado da aplicação cliente e se recuperar de uma forma mais ou menos seguro?

Foi útil?

Solução

Este é um erro no Oracle (ou chamá-lo um recurso) até 11.1.0.6 e disseram que o patch do Oracle 11g Release 1 (remendo 11.1.0.7), que tem a correção. Precisa ver isso. Se isso acontecer você terá que cancelar (kill) o fio de executar essa ação. Não boa abordagem embora

Outras dicas

Em toda a minha DB esquema eu tenho uma tabela com um registro constante. Apenas sondar essa tabela periodicamente pelo pedido SQL simples. Todos os outros métodos pouco fiáveis.

Há uma API set_timeout em OTL que possa ser útil para isso.

Edit: Na verdade, ignorar isso. set_timeout não funciona com OCI. Ter um olhar para a descrição set_timeout de aqui onde ele descreve uma técnica que pode ser usada com OCI

Parece que você precisa para disparar uma consulta ao banco de dados (por exemplo SELECT * FROM dual;), em seguida, se o banco não respondeu dentro de um determinado período de tempo, suponha que o servidor tenha morrido e reagir em conformidade. Eu tenho medo Eu não sei C / C ++, mas você pode usar multi-threading para disparar a declaração, em seguida, aguardar a resposta, sem desligar a aplicação?

Isso funciona - eu fiz exatamente o que você está procurando. Tem um processo pai (A) criar um processo filho (B). O processo de criança (B) liga-se a base de dados, executa uma consulta (algo como "selecione 1 a_Table" - você vai obter um melhor desempenho se você evitar o uso de "dual" para isso e criar sua própria tabela). Se (B) for bem sucedida, então ele escreve que ele foi bem sucedido e sai. (A) está esperando por uma quantidade de tempo especificada. Eu usei 15 segundos. Se (A) detecta que (B) ainda está em execução - então ele pode assumir que o banco de dados é hung -. Ele mata (B) e toma as ações necessárias (como chamar me no telefone com uma SMS)

Se você configurar SQL * NET para usar um tempo limite provavelmente você vai notar que consultas grandes falhará por causa disso. A OCI set_timeout configuração também irá causar isso.

Há uma maneira manual para evitar isso. Você pode abrir um firewall e fazer algo como banco de dados de ping após cada período de tempo especificado. Desta forma, a conexão com o banco não vai se perder.

idéia

If (current_time - lastPingTime > configuredPingTime)
{
     //Dummy query
     select 1 from dual;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top