2012-03-18 19 views
5

Ho copiato il seguente esempio da un sito web della biblioteca SQLite Java:Chiarimento di Java/SQLite batch e auto-commit

PreparedStatement prep = conn.prepareStatement("insert into people values (?, ?);"); 
    prep.setString(1, "Gandhi"); 
    prep.setString(2, "politics"); 
    prep.addBatch(); 
    prep.setString(1, "Turing"); 
    prep.setString(2, "computers"); 
    prep.addBatch(); 
    conn.setAutoCommit(false); 
    prep.executeBatch(); 
    conn.setAutoCommit(true); 

sto lottando per capire il significato di commutazione autoCommit() entrambi i lati della executeBatch(). Si limita semplicemente a impedire l'esecuzione di un commit per ogni singola operazione batch? Quindi un singolo commit "bulk" sarà effettuato da setAutoCommit(true).

Grazie.

+0

Ho aggiunto una risposta a ciò che contraddice alcune delle informazioni nella risposta accettata. FYI. – Gray

risposta

8

Il commit automatico viene disabilitato prima del batch perché l'abilitazione del commit automatico si impegna (ovvero, attendere che la sincronizzazione si verifichi, il che significa che attenderà che i dati vengano effettivamente scritti nella memoria persistente come il disco rigido) dopo ogni riga inserita.

Se il commit automatico è falso, non attenderà la sincronizzazione.

La differenza nell'attesa di sincronizzazione e non attesa è la garanzia che i dati siano effettivamente sul disco rigido o nel buffer (che potrebbe essere bufferato IO o buffer di disco rigido).

In breve, la disattivazione del commit automatico offre un miglioramento delle prestazioni. E penso che il commit automatico di default sia abilitato.

Un altro modo di ottimizzazione

Se si desidera avere commit automatico su ON e ancora bisogno di aumentare le prestazioni solo cercare di iniziare come transazione prima l'operazione di travaso e il commit della transazione dopo. In questo modo sqlite non eseguirà il commit automatico dopo ogni inserimento e darà un buon incremento delle prestazioni.

EDIT:

Quando si iniziare una transazione che si sta solo disattivazione di Auto commettere per tale operazione e sarà di nuovo 'on', una volta transazione è finita. L'ausilio del commit automatico è quando si inseriscono/aggiornano le righe separatamente (non come batch), quindi non è necessario avviare una transazione esplicitamente per ogni inserimento/aggiornamento. E per quanto riguarda l'impostazione del commit automatico su true, dopo il fatto , non richiede il commit. Se esegui il commit automatico true e tutto ciò che hai già inserito/aggiornato non avrà alcun effetto e non avrà le stesse garanzie come vero commit automatico prima di eseguire tali inserimenti/aggiornamenti.

Here's some information about speeding up Sqlite INSERTs.

+0

Grazie per la risposta dettagliata. Hai ragione, 'autoCommit()' è abilitato di default. Quando viene chiamato 'autoCommit (true)', sai se i dati del batch verranno scritti nella memoria permanente? – c24w

+0

sì, sarà scritto. Non avrà la stessa garanzia di auto commit on. Avevo aggiornato i miei ans per darti un'altra opzione. – havexz

3

@havexz risposta fornisce alcune informazioni errate così avevo pensato che vorrei aggiungere una risposta per i posteri.

  1. FYI, SQLite non supporta il commit automatico direttamente. La chiamata a setAutoCommit(false) su una connessione JDBC SQLite avvia effettivamente una transazione con i driver Xerial e Zentus. Vedere questo SO domanda: How to disable autocommit in sqlite4java?

  2. Sono quasi positivo che l'impostazione di auto-commit di nuovo a vera volontà non fare un commit sulla connessione al database. La prossima affermazione che termina manterrà qualsiasi cambiamento in sospeso, ma devi fare uno conn.commit(); per impegnare effettivamente le operazioni batch.

  3. L'avvio di una transazione in pratica equivale a disattivare il commit automatico, quindi è improprio implicare che è possibile lasciare l'auto-commit attivo all'interno di una transazione.

+0

Grazie per il tuo intervento Mr Gray! Sono ancora confuso perché il codice [qui] (http://www.zentus.com/sqlitejdbc/) suggerisce di usare 'setAutoCommit (...)', come per il mio post originale. Inoltre, come sarebbe 'conn.exec (" COMMIT ")' e 'conn.commit()' compare? Quest'ultimo essenzialmente "avvolge" il primo? Grazie! – c24w

+1

Forse il driver Zentus sta facendo una transazione sotto le coperte. A proposito, il driver Xerial Sqlite è di gran lunga superiore allo Zentus. http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC – Gray

+0

RE: 'conn.exec (" COMMIT ")', giusto, duh, l'ho cambiato in 'conn.commit()'. – Gray