2010-01-26 12 views
5

He observado el siguiente comportamiento.Java JDBC clearBatch() y la memoria del montón

Tengo un archivo de unos 3 MB que contiene varios miles de filas. En las filas, divido y creo una declaración preparada (alrededor de 250 000 declaraciones).

Lo que hago es:

preparedStatement 
addBatch 
do for every 200 rows { 
executeBatch 
clearBatch(). 
} 

al final

commit() 

El uso de memoria aumentará a alrededor de 70 MB sin error de falta de memoria. ¿Es posible bajar el uso de la memoria? y tienen el comportamiento transaccional (si uno falla, todos fallan). Pude bajar la memoria haciendo commit con executeBatch y clearBatch ... pero esto causará una inserción parcial del conjunto total.

+1

Esto podría ser muy dependiente de la calidad del controlador JDBC - cuál son estás usando? – skaffman

+0

He cambiado de 200 filas a 10000 y el tiempo para ejecutar ahora es de 37 segundos. Parece que se usa el mismo tamaño. Estoy usando H2's org.h2.jdbcx.JdbcConnectionPool, los datos se almacenan como un archivo ... no en la memoria. Estoy intentando construir una aplicación local sin un servidor de base de datos como Oracle, MySQL, etc. – Firone

+0

¿Está seguro de que el uso de memoria alta está relacionado con el procesamiento de la base de datos y no con la E/S de archivo de la importación? – Timothy

Respuesta

2

Puede insertar todas las filas en una tabla temporal con la misma estructura y si todo está bien. deje que la base de datos los inserte en la tabla de destino usando: insert into target (select * from temp). En caso de que falle la importación en la tabla temporal, no ha cambiado nada en su tabla de destino.

EDIT: sintaxis fija

-1

También puede utilizar la función de JDBC 2.0 "procesamiento por lotes".

  1. Indica tu DbConnection usando connection.setAutoCommit(false)
  2. Añadir lotes a su declaración usando statement.addBatch(sql_text_here)
  3. Una vez que los lotes son todos cargados, ejecutarlo usando: statement.executeBatch()
  4. COMPROMÉTANSE usando connection.commit()
  5. excepciones de captura y su reversión según sea necesario usando connection.rollback()

Más sobre el manejo para la restitución excepción ... aquí es un típico controlador de excepciones de reversión:

catch(BatchUpdateException bue) 
    { 
    bError = true; 
    aiupdateCounts = bue.getUpdateCounts(); 

    SQLException SQLe = bue; 
    while(SQLe != null) 
    { 
     // do exception stuff 

     SQLe = SQLe.getNextException(); 
    } 
    } // end BatchUpdateException catch 
    catch(SQLException SQLe) 
    { 
    ... 

    } // end SQLException catch 

leer hasta aquí: http://java.sun.com/developer/onlineTraining/Database/JDBC20Intro/JDBC20.html#JDBC2015

+2

¿No es eso lo que describió actualmente, excepto el uso de declaraciones preparadas? – Anonym

+0

Parcialmente, sí (pasos 1-4). Pero el paso 5 permitirá una reversión completa de la transacción si falla. – Timothy

+0

La reversión no es relevante para el problema. – skaffman

Cuestiones relacionadas