OutOfMemory e Corrupção de Banco de Dados

4 respostas
M

Olá pessoal!

procurei por aqui e no Google e não encontrei nada a respeito, então recorro a vocês.
Tenho uma aplicação java que dá OutOfMemory. Até aí, o problema é conhecido e estou trabalhando nisso. No pior caso, enquanto não consigo fazer uma uso otimizado da memória (ou detectar o meu ponto de vazamento), acabo reiniciando a aplicação, o que me permite utilizar de novo por algum tempo.
O problema é que quando ocorre OutOfMemory, os dados da minha aplicação ficam inconsistente. Isso inclui dados que já estavam consistentes antes, ou seja, a aplicação corrompe dados que já haviam sido comitados.

Exemplo: cadastrei um funcionário. Consultei o funcionário e tudo está certo (inclusive consultando no banco via SQL). Em seguida, vou cadastrar os filhos do funcionário e acaba dando OutOfMemory. Quando reinicio a aplicação, não apenas os filhos possuem dados errados, como também o funcionário.

A pergunta é: o gerenciamento de memória da VM (usado junto com Hibernate, Spring e Oracle) podem provocar esse erro, ou a minha aplicação possui um bug que eu ainda não consegui encontrar?

Desde já agradeço a ajuda!
Takeda

4 Respostas

Paulo_Silveira

eu tambem tenho nisso numa aplicacao. se eu deixar 20 dias sem reiniciar, da OOm e o MALDITO tomcat loga o Error e ENGOLE. sendo que na documentacao esta BEM explicitado que voce nao deve segurar a execucacao ao ocorrer um OOM.

voce deve dar um jeito de nao engulir a OOM, no primeiro momento que ela ocorrer ela deve subir e em algum lugar voce desliga a aplicacao.

use um pofiler pra saber o que voce esta segurando que nao era pra segurar.

Rafael_Steil

Voce deveria focar em resolver o OOM primeiro, ao inves de focar nos problemas de dados corrompidos.
Talvez uma coisa nem esteja associada a outra, mas resolver o OOM deveria ser a sua prioridade.

Rafael

louds

Isso é teoricamente possivel de acontecer dependendo da qualidade do driver o comportamento padrão do banco no caso de transações interrompidas sem commit/rollback.

O driver pro teu banco pode estar fazendo burradas quando um OOM acontece dentro dele, procure no google a respeito.

Ou então pode estar ocorrendo da transação estar sendo interrompida antes do commit/rollback e o teu RDBMS estar dando commit para você.

Cenario:

1. begin trs
2. update xxx
    insert xxx
2.1. A JVM é terminada 
3. ok ? commit else rollback

Fora isso não posso sugerir muito mais sem maiores informações sobre o ambiente.

Se não tiver outra maneira, faça o seguinte:

try {
  commited = false;
  ....
  commit();
  commited = true;
} catch(OutOfMemoryError e) {
  doMemHedge();
} finally {
   if(!commited) rollback();
}

static byte[] hedge = new byte[1000 * 100];
void doMemHedge() {
  hedge = null;
  System.gc();
}

Esse exemplo simplifica bastante a coisa por que não leva em conta a reaquisição de memoria de hedging nem JVMs que usam areas distintas para tamanhos diferentes de objetos.

Arcadex

Parceiro,

minha aplicação é feita com (Spring + Hibernate + Oracle) também.
No ambiente do cliente ocorre muito outOfMemory, porém nunca houve problema de corrupção de dados ou falha no controle de transação.

Criado 11 de janeiro de 2005
Ultima resposta 13 de abr. de 2005
Respostas 4
Participantes 5