Pergunta

Eu estou usando hibernate 3 com c3p0 para um programa que constantemente extrai dados de uma fonte e escreve-o para um banco de dados. Agora o problema é que o banco de dados pode se tornar indisponível por algumas razões. (No caso mais simples: eu simplesmente desligá-lo)

Se alguma coisa está prestes a ser escrito para o banco de dados não deve haver qualquer exceção - a consulta deve esperar por toda a eternidade até que o banco de dados torna-se disponível novamente. Se não estou enganado esta é uma das coisas que o pool de conexão poderia fazer para mim:. Se há um problema com o db, apenas repetir para conectar - no pior caso para o infinito

Mas em vez disso eu recebo uma exceção cano quebrado, às vezes seguido de conexão recusada e, em seguida, a exceção é passada para o meu próprio código, o que não deveria acontecer.

Mesmo se eu capturar a exceção, como poderia eu limpa reinicializar hibernar novamente? (Até agora, sem c3p0 i simplesmente construiu a fábrica de sessão de novo, mas eu não ficaria surpreso se isso pudesse vazar conexões (ou é ok para fazê-lo?)).

O banco de dados é Virtuoso edição de código aberto.

Meu hibernate.xml.cfg c3p0 config:

<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>  
<property name="hibernate.c3p0.breakAfterAcquireFailure">false</property>
<property name="hibernate.c3p0.acquireRetryAttempts">-1</property>
<property name="hibernate.c3p0.acquireRetryDelay">30000</property>
<property name="hibernate.c3p0.automaticTestTable">my_test_table</property>

<property name="hibernate.c3p0.initialPoolSize">3</property>
<property name="hibernate.c3p0.minPoolSize">3</property>
<property name="hibernate.c3p0.maxPoolSize">10</property>

btw:. A tabela de teste é criado e eu recebo toneladas de depuração output- assim parece que realmente lê a configuração

Foi útil?

Solução

Bem, parece que BoneCP tem realmente implementado este. Ele pode ser configurado para gravar a transação e reproduzi-lo em cima de rede ou banco de dados de falha:

http: // jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPConfig.html#setTransactionRecoveryEnabled(boolean)

Outras dicas

Se não estou enganado esta é uma das coisas que o pool de conexão poderia fazer para mim:. Se há um problema com o db, apenas repetir para conectar - no pior caso para o infinito

Você está enganado. Um pool de conexão é apenas ... um pool de conexão, ele contém algumas conexões físicas já estabelecidas para o banco de dados e é usado para evitar a sobrecarga de criar essas conexões quando você precisa de um deles.

Dito isso, essas conexões podem se tornar obsoleto (por exemplo, se você reiniciar o banco de dados). Felizmente, a maioria dos pools de conexão pode ser configurado para testar se uma conexão ainda é válido e renová-los antes de distribuí-los. c3p0 suportam esta funcionalidade conforme documentado no Configurando Conexão Testing e você está na verdade, já está usando uma das várias opções. Assim, as ligações devem ser renovadas quando o banco de dados de volta.

Mas não espere que seu aplicativo para ser magicamente suspensa quando o banco de dados vai para baixo, uma piscina não vai fazer isso.

Obrigado pela resposta. Parece que eu só não entendi o último parágrafo da seção http://www.mchange.com/projects/c3p0/index.html# configuring_recovery

Porque no começo parece c3p0 poderia fazê-lo (detectar conexões obsoletos e Repetir para conexões adquirir para toda a eternidade sem nunca lançar uma exceção para o código do aplicativo (a menos, claro, quando seu um erro relacionado com a instrução SQL e não ao conexão), mas no último parágrafo - que é escrito em bastante confuso caminho - parece como se c3p0 não pode garantir que 100%

.

Assim, a minha solução foi fazer um pequeno wrapper para os métodos i necessários a partir da interface de conexão JDBC, que tentará se reconectar se uma consulta falhar devido a um erro de conexão. Claro, é um pouco hacky, porque eu prefiro ter meus componentes usar a conexão da interface padrão em vez de minha própria interface, mas pelo menos o seu trabalho de forma limpa agora.

Você está esquecendo:

  • O que sobre suas transações que foram iniciados?
  • O que sobre qualquer PreparedStatements que foram enviados para o DB já?
  • etc

A sua aplicação terá, portanto, para reiniciar a transação. A única possível maneira que eu posso pensar é para o pool de conexão para manter o controle de cada chamada para o identificador de conexão e repetir aqueles em caso de erro, mas isso seria muito abrandar o pool de conexão.

No caso de BoneCP ( http://jolbox.com ), a piscina detecta uma falha ocorreu por captura a exceção lançada pelo driver JDBC primeira e manuseá-lo por qualquer sinalização essa conexão como defeituoso ou então recriando todo o pool de conexão.

Edit:. Ele está sendo tratado agora

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top