Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Fechar um conjunto de resultados de streaming (usando mysql jdbc) leva muito tempo


Então, conforme postado no meu comentário à pergunta, a resposta oficial do conector MySQL é que você precisa transmitir todo o conjunto de resultados para que ele seja fechado (http://dev.mysql.com/doc/refman/5.5/en/connector-j- reference-implementation-notes.html ). Além disso, você não pode realizar mais consultas enquanto um resultado de streaming estiver ocorrendo.

Como um hack completamente nojento, usei reflexão para descer em RowDataDynamic (ver. 5.1.24) e fingir uma exceção interrompida, assim:
    final Class<?> rdClass = rd.getClass();
    final Field isInterruptedField = rdClass.getDeclaredField("isInterrupted");
    isInterruptedField.setAccessible(true);  // override 'protected' visibility
    isInterruptedField.set(rd, true);

Observe que você terá que percorrer qualquer objeto sobre o qual tenha uma alça para chegar ao ResultSet. Para mim, eu estava usando a classe ScrollableResults do Hibernate. Isso significava obter a referência ResultSet dele (sua superclasse, na verdade), e então RowData a partir daí.

Isso permitirá que a operação de fechamento ocorra sem transmitir o restante dos resultados ENTÃO Eu recebo uma exceção devido ao tamanho do pacote incompatível quando tento reverter a transação (que eu apenas pego e ignoro). Usando o Atomikos como o pool de conexões, verei avisos sobre as próximas conexões à medida que as coisas forem limpas, mas tudo ainda funciona bem.

Claramente, essa abordagem pode não funcionar para todos, mas pelo menos é uma solução alternativa ao fazer o processamento por meio da consulta do banco de dados ou escrever uma lógica mais complicada para recuperar resultados em lotes simplesmente não funcionará.