2011-11-12 24 views
22

He leído muchos temas, pero no puedo entender la respuesta a la pregunta: ¿es posible leer y escribir simultáneamente?SQLite lectura y escritura simultáneas

Tengo un hilo de fondo que actualiza algunos datos y la IU necesita pequeños datos almacenados en DB. Entonces, en la interfaz de usuario se realiza la operación SELECCIONAR hilo. Pero bloquea cuando la actualización está en progreso. Como resultado, la IU se congela durante varios segundos.

¿Alguien tiene éxito en la lectura de DB al escribir?


Es posible leer y escribir en DB en iPhone. ¿La razón de tal diferencia está en la implementación sincrónica de wrapper en funciones sqlite nativas?

+5

"Por lo tanto, en el subproceso UI se realiza la operación SELECT" -> sáquelo del subproceso UI. – hovanessyan

+2

Hay una operación simple como SELECCIONAR el nombre DESDE some_table WHERE _id = No mostrar el nombre durante unos segundos no mucho mejor de la congelación – HighFlyer

Respuesta

54

en Android 3.0 y superiores SQLiteDatabases compatibilidad con el modo WAL (registro de escritura anticipada):

Cuando el registro de escritura anticipada no está activado (por defecto), no es posible que lee y escribe a producirse en la base de datos al mismo tiempo . Antes de modificar la base de datos, el escritor adquiere implícitamente un bloqueo exclusivo en la base de datos que impide que los lectores accedan a la base de datos hasta que se completa la escritura.

Por el contrario, cuando el registro de escritura anticipada está habilitado, las operaciones de escritura se producen en un archivo de registro separado que permite que las lecturas procedan al al mismo tiempo. Mientras está en progreso una escritura, los lectores de otros hilos percibirán el estado de la base de datos tal como estaba antes de que comenzara la escritura . Cuando finalice la escritura, los lectores de otros hilos verán el nuevo estado de la base de datos.

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#enableWriteAheadLogging()

Para iniciar una transacción en el modo WAL utilizar beginTransactionNonExclusive() en lugar de beginTransaction(). Mientras beginTransaction() inicia una transacción en modo exclusivo, beginTransactionNonExclusive() inicia una en el modo inmediato

  • modo exclusivo utiliza bloqueos exclusivos (http://www.sqlite.org/lockingv3.html#excl_lock) que significa ninguna otra conexión de base de datos excepto para las conexiones read_uncommitted será capaz de leer la base de datos y ninguna otra conexión sin excepción podrá escribir la base de datos hasta que se complete la transacción
  • El modo INMEDIATO usa bloqueos reservados (http://www.sqlite.org/lockingv3.html#reserved_lock) lo que significa que ninguna otra conexión de base de datos podrá escribir en la base de datos o INICIAR INMEDIATO o COMENZAR EXCLUSIVAMENTE Sin embargo, otros procesos pueden seguir leyendo desde la base de datos.

En palabras más simples: llamar beginTransactionNonExclusive() de modo inmediato y podemos leer mientras otro hilo está escribiendo (el estado antes de que comenzara la operación de escritura porque no vamos a utilizar conexiones read_uncommitted ->http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Dirty_reads).

+0

¡Impresionante! Esta información es muy importante, pero se perdió. ¡Gracias por tu respuesta detallada! – HighFlyer

+0

El modo WAL me inhabilitará para admitir todas las API menos de API 16. ¿Hay alguna otra solución? –

+6

El modo WAL es compatible con API 11 en (Honeycomb). La diferencia entre API 11 y API 16 es que puedes abrir la base de datos en modo WAL con API 16 usando el modo Context.MODE_ENABLE_WRITE_AHEAD_LOGGING mientras que tienes que abrirlo en uno de los modos disponibles en API11-15 y luego cambiar al modo WAL usando SQLiteDatabase.enableWriteAheadLogging(). Abrir en modo WAL es considerablemente más rápido, pero eso es lo que tienes. Antes de Honeycomb, simplemente no hay modo WAL, lo que significa que la aplicación funcionará más despacio, pero "debería" al menos no tener otros efectos secundarios. –

1

No es posible leer & escribir simultáneamente. Sin embargo, si tiene las clases de base de datos SQLite configuradas correctamente (instancia única de sus clases auxiliares DB &), diferentes subprocesos deberían poder tomar la conexión DB sincrónicamente para que no haya un desfase notable.

También parece que está intentando hacer un back-end (escribir en el archivo db) con su subproceso de interfaz de usuario. No deberías estar haciendo esto. Cree una AsyncTask para manejar esto en lugar de tener que manejar su subproceso de interfaz de usuario.

Consulte la documentación de SQLiteOpenHelper. Aquí hay una publicación anterior que habla de esto también: What are the best practices for SQLite on Android?

3

No puede leer y escribir al mismo tiempo. SQLite es una base de datos sin servidor y basada en archivos.

Desde el SQLite FAQ:

"Cuando cualquier proceso quiere escribir, se debe bloquear todo el archivo de base de datos para la duración de su actualización. Pero que normalmente sólo toma unos pocos milisegundos. Otros procesos sólo tiene que esperar en el escritor de termine y continúe con su negocio. Otros motores de bases de datos SQL incorporados normalmente solo permiten que un solo proceso se conecte a la base de datos de una vez ".

+3

Vota abajo porque la respuesta es incorrecta. Desde Honeycomb on (que ya estaba fuera cuando se dio la respuesta) es posible leer/escribir "al mismo tiempo" (ver mi propia respuesta) –

+0

No veo nada en la pregunta original que dice "en Honeycomb" – dnuttle

+9

La pregunta es: "¿es posible leer y escribir simultáneamente?", Su respuesta es: "No se puede leer y escribir al mismo tiempo". La respuesta es incorrecta porque puedes si estás en Honeycomb o superior. –

3

Comenzando con API 11 Android tiene soporte para modo WAL. Mantiene los datos originales intactos durante la transacción, por lo que otros subprocesos pueden leer cuando se está ejecutando la transacción. Puede comprobar mi artículo para más detalles sobre el modo WAL:

http://www.skoumal.net/en/parallel-read-and-write-in-sqlite/

También debe evitar la ejecución de consultas de bases de datos en hilo de interfaz de usuario. Siempre puede volverse lento y bloquear tu UI.

Cuestiones relacionadas