2010-01-26 10 views
5

Ho notato il seguente comportamento.Java JDBC clearBatch() e memoria heap

Ho un file di circa 3 MB contenente diverse migliaia di righe. Nelle righe ho diviso e creato una dichiarazione preparata (circa 250.000 dichiarazioni).

Quello che faccio è:

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

alla fine

commit() 

L'utilizzo della memoria aumenterà a circa 70MB, senza errore di memoria insufficiente. È possibile ridurre l'utilizzo della memoria? e hanno il comportamento transazionale (se uno fallisce, tutti falliscono). Sono stato in grado di abbassare la memoria eseguendo il commit con lo executeBatch e clearBatch ... ma ciò causerà un inserimento parziale del set totale.

+1

Questo potrebbe essere molto dipende dalla qualità del driver JDBC - quale sono stai usando? – skaffman

+0

Sono passato da 200 a 10000 e il tempo di esecuzione è ora di 37 secondi. Sembra che sia stata usata la stessa misura. Sto usando il file org.h2.jdbcx.JdbcConnectionPool di H2 i dati sono memorizzati come file .. non in memoria. Sto cercando di creare un'applicazione locale senza un server di database come oracle, mysql, ecc. – Firone

+0

Sei sicuro che l'elevato utilizzo della memoria è legato all'elaborazione del database e non all'I/O del file dall'importazione? – Timothy

risposta

2

È possibile inserire tutte le righe in una tabella temporanea con la stessa struttura e se tutto è a posto. lasciare che il database li inserisca nella tabella di destinazione utilizzando: insert into target (select * from temp). Nel caso in cui l'importazione nella tabella temporanea abbia esito negativo, non è stato modificato nulla nella tabella di destinazione.

EDIT: sintassi fissa

-1

Si potrebbe anche utilizzare la funzione di 2.0 "batch" JDBC.

  1. impostare il proprio DbConnection utilizzando connection.setAutoCommit(false)
  2. Aggiungi lotti per la sua dichiarazione con statement.addBatch(sql_text_here)
  3. Una volta che i lotti sono tutti caricati, eseguirlo tramite: statement.executeBatch()
  4. commetterlo usando connection.commit()
  5. eccezioni di cattura e rollback se necessario utilizzando connection.rollback()

più sul trattamento per il rollback eccezione ... ecco un tipico gestore di eccezioni di rollback:

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 

leggere fino qui: http://java.sun.com/developer/onlineTraining/Database/JDBC20Intro/JDBC20.html#JDBC2015

+2

Non è quello che ha descritto che fa attualmente, tranne l'utilizzo di dichiarazioni preparate? – Anonym

+0

In parte, sì (passaggi 1-4). Ma il passaggio 5 consentirà un rollback completo della transazione se fallisce. – Timothy

+0

Il rollback non è rilevante per il problema. – skaffman

Problemi correlati