2012-03-18 8 views
5

Copié el siguiente ejemplo de un sitio web de la biblioteca SQLite Java:Aclaración de Java/SQLite lotes y 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); 

estoy luchando para comprender la importancia de alternar autoCommit() ambos lados de executeBatch(). ¿Simplemente evita que se realice una confirmación para cada operación de lote individual? Por lo tanto, se realizará una única confirmación 'bulk' por setAutoCommit(true).

Gracias.

+0

He agregado una respuesta a esto que contradice parte de la información en la respuesta aceptada. FYI. – Gray

Respuesta

8

La confirmación automática está desactivada antes del lote porque la confirmación automática confirmará (es decir, esperará la sincronización, lo que significa que esperará que los datos se escriban en el almacenamiento persistente como el disco duro) después de cada fila que se inserte.

Si la confirmación automática es falsa, no esperará la sincronización.

La diferencia en la espera de la sincronización y no esperar es la garantía de si los datos están realmente en el disco duro o en el búfer (que podría almacenarse temporalmente en el búfer o en el búfer del disco duro).

En resumen, deshabilitar la confirmación automática le da impulso de rendimiento. Y creo que de forma predeterminada la confirmación automática está habilitada.

Otra forma de optimización

Si usted quiere tener confirmación automática ON y todavía necesita aumento de rendimiento sólo tratar de comenzar tan transacción antes de la operación por lotes y confirmar la transacción después. De esta forma, sqlite no se confirmará automáticamente después de cada inserción y dará un buen impulso al rendimiento.

EDIT:

Al iniciar una transacción sólo está deshabilitando automático cometer para esa transacción y será de nuevo 'en' una vez que la transacción ha terminado. Lo que confirma automáticamente ayuda es cuando está insertando/actualizando filas por separado (no como lote), entonces no tiene que iniciar una transacción explícitamente para cada inserción/actualización. Y en cuanto a establecer el autocompromiso en verdadero, después del hecho , no llama a commit. Si hace que la confirmación automática sea verdadera y lo que haya insertado/actualizado no tendrá ningún efecto y no tendrá las mismas garantías que el autocompromiso verdadero antes de realizar esas inserciones/actualizaciones.

Here's some information about speeding up Sqlite INSERTs.

+0

Gracias por la respuesta detallada. Estás en lo cierto, 'autoCommit()' está habilitado de forma predeterminada. Cuando se llama a 'autoCommit (true)', ¿sabe si los datos del lote se escribirán en el almacenamiento persistente? – c24w

+0

sí, se escribirá. No tendrá la misma garantía que con la confirmación automática. Había actualizado mi ans para darle otra opción. – havexz

3

@havexz respuesta da una información incorrecta por lo que había pensado que me gustaría añadir una respuesta para la posteridad.

  1. FYI, SQLite no admite la confirmación automática directamente. Llamar al setAutoCommit(false) en una conexión SQLite JDBC realmente inicia una transacción con los controladores Xerial y Zentus. Ver esta cuestión de forma: How to disable autocommit in sqlite4java?

  2. Estoy casi seguro de que el establecimiento de confirmación automática de nuevo a la verdadera voluntad no hacer una confirmación de la conexión de base de datos. La próxima instrucción que termine persistirá cualquier cambio pendiente, pero debe hacer un conn.commit(); para realmente comprometer las operaciones por lotes.

  3. Iniciar una transacción básicamente es lo mismo que desactivar el autocompromiso, por lo que es incorrecto implicar que puede dejar el autocompromiso mientras está dentro de una transacción.

+0

Gracias por su entrada Sr. Gray! Todavía estoy confundido por qué el código [aquí] (http://www.zentus.com/sqlitejdbc/) sugeriría usar 'setAutoCommit (...)', según mi publicación original. Además, ¿cómo compararían 'conn.exec (" COMMIT ")' y 'conn.commit()'? ¿El último esencialmente "envuelve" al primero? ¡Gracias! – c24w

+1

Tal vez el controlador de Zentus está haciendo una transacción bajo las sábanas. Por cierto, el controlador Xerial Sqlite es muy superior al Zentus. http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC – Gray

+0

RE: 'conn.exec (" COMMIT ")', a la derecha, duh, lo he cambiado a 'conn.commit()'. – Gray