2010-01-26 6 views
5

J'ai remarqué le comportement suivant.Java JDBC clearBatch() et la mémoire tas

J'ai un fichier d'environ 3 Mo contenant plusieurs milliers de lignes. Dans les lignes, je diviser et créer une déclaration préparée (environ 250 000 déclarations).

Ce que je fais est:

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

à la fin

commit() 

L'utilisation de la mémoire augmente à environ 70 Mo sans erreur de dépassement de mémoire. Est-il possible de réduire l'utilisation de la mémoire? et ont le comportement transactionnel (si tout échoue, tout échoue). J'ai été capable d'abaisser la mémoire en faisant un commit avec les executeBatch et clearBatch ... mais cela entraînera une insertion partielle de l'ensemble total.

+1

Cela pourrait être très dépendante de la qualité du pilote JDBC - lequel sont vous utilisez? – skaffman

+0

J'ai changé de 200 lignes à 10000 et le temps d'exécution est maintenant de 37 secondes. On dirait que la même taille est utilisée. J'utilise le H2 org.h2.jdbcx.JdbcConnectionPool les données sont stockées sous forme de fichier .. pas en mémoire. Je tente de construire une application locale sans serveur de base de données comme Oracle, MySQL, etc. – Firone

+0

Etes-vous certain que l'utilisation de la mémoire élevée est liée au traitement de la base de données, et non à l'E/S de fichier? – Timothy

Répondre

2

Vous pouvez insérer toutes les lignes dans une table temporaire avec la même structure et si tout va bien. laissez la base de données les insérer dans la table cible en utilisant: insert into target (select * from temp). Si l'importation dans la table temporaire échoue, vous n'avez rien modifié dans votre table cible.

EDIT: syntaxe fixe

-1

Vous pouvez également utiliser la fonctionnalité JDBC 2.0 "de traitement par lots".

  1. Définir vos DbConnection en utilisant connection.setAutoCommit(false)
  2. Ajouter lots à votre déclaration en utilisant statement.addBatch(sql_text_here)
  3. Une fois vos lots sont tous chargés, l'exécuter en utilisant: statement.executeBatch()
  4. Commit à l'aide connection.commit()
  5. Catch exceptions et rollback au besoin en utilisant connection.rollback()

Plus d'informations sur la gestion des exceptions pour rollback ... voici un gestionnaire d'exception rollback typique:

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 

Lire ici: http://java.sun.com/developer/onlineTraining/Database/JDBC20Intro/JDBC20.html#JDBC2015

+2

N'est-ce pas ce qu'il a décrit qu'il fait actuellement, sauf en utilisant des déclarations préparées? – Anonym

+0

Partiellement, oui (étapes 1 à 4). Mais l'étape 5 permettra une annulation complète de la transaction si elle échoue. – Timothy

+0

La restauration n'est pas pertinente au problème. – skaffman