Re:Especificação de implementação de java.sql.ResultSet

4 respostas
T

Se seu resultset foi aberto como TYPE_FORWARD_ONLY (que é o default), em um determinado instante de tempo há apenas um registro lido na memória do cliente. A cada vez que se executa next(), o registro anterior é descartado.

Se você usar algum outro modo de abertura, em algum lugar é necessário armazenar alguma coisa - por exemplo, ou apenas as chaves (TYPE_SCROLL_SENSITIVE), ou todo o resultset (TYPE_SCROLL_INSENSITIVE). Onde isso é armazenado depende do driver JDBC; pode ser no próprio client, ou talvez no servidor de banco de dados.

4 Respostas

T

O Javadoc do package java.sql aponta para a trilha do tutorial de JDBC ( http://java.sun.com/docs/books/tutorial/jdbc/overview/index.html ), que é um pouco vaga em termos arquiteturais, até porque a especificação do JDBC dá bastante margem para o implementador do driver fazer o que achar melhor. Quanto aos detalhes de como os dados são armazenados ou não em memória, acho que depende bastante da implementação do driver usado. Mas usualmente TYPE_FORWARD_ONLY (o padrão) faz com que haja, em cada momento, apenas um registro do resultado em memória.

theBalrog

Bom dia, pessoal.

Bem, não sei se alguém sabe me dizer, mas li o Javadoc 1.5 e a especificação JDBC 3.0 e não encontrei nada a respeito.
Estou com uma aplicação que vou refatorada. Em uma funcionalidade em particular dessa aplicação, existe a possibilidade de montar uma lista de pessoas para se enviar e-mails.

Na versão anterior, a classe que fazia a leitura dessa lista e o disparo dos e-mails acessava diretamente o banco de dados e fazia seu processamento de negócio no while que iterava pelo ResultSet (sim, fazia tudo isso… ugh).
Nessa nova versão, fizemos DAO, separamos a lógica de disparo para uma classe específica, e com isso a funcionalidade ficou bem separada de acordo com responsabilidade.

Aqui que o bicho pega: a versão anterior, nós conseguíamos enviar 30.000 e-mails fácil e rapidamente. Na nova versão, tenho problemas pra enviar 4.000 sem dar falta de memória ( OutOfMemoryError na PermGen).

A primeira coisa que pensei quando vi o erro foi: “estão sendo 4.000 objetos na memória, pelo menos”. Mas logo lembrei da primeira versão que enviava 30.000 dando risada.

A dúvida aqui é: quando itero pelo ResultSet ele mantém um cursor. Isso quer dizer que cada vez que eu executo next() no ResultSet, ele pega os dados daquela linha e carrega na memoria? Meu palpite é que sim, pois senão teria problemas ao retornar 30.000 linhas no meu SELECT.

Um abraço a todos.

theBalrog

O ResultSet é criado com o método default do PreparedStatement, então tudo indica que é FORWARD_ONLY. Sendo assim, isso explica muita coisa.
Você tem alguma literatura que explique isso thingol?

Valeu pela informação

theBalrog

Entendo.

Bem, a julgar que essa aplicação, tanto antes como agora, mantém um banco de dados Oracle, imagino que eles devam manter um cursor aberto no banco, como você também supôs inicialmente.

Bem, vou fazer um plano para mudar esse cenário.

Obrigado pela ajuda.

Criado 6 de maio de 2009
Ultima resposta 6 de mai. de 2009
Respostas 4
Participantes 2