La escritura concurrente a la base de datos android (de múltiples servicios)?

Tengo un problema serio con la base de datos sqlite de android y la escritura concurrente. Para mejores explicaciones, te daré un ejemplo de la vida real:

Tengo un widget de escritorio, donde estoy mostrando una lista de elementos de mi base de datos (y en segundo plano tengo DataService, que en intervalos regulares recoge datos frescos de mi servidor remoto, y actualizar mi base de datos con ellos). Así que – cuando hago clic en algún elemento de la lista, necesito actualizar el elemento pulsado (= escribir operación) en la base de datos. PERO cuando hago clic en el elemento exactamente en el momento, cuando DataService está actualizando datos frescos en mi base de datos, por supuesto registra un error como este:

android.database.sqlite.SQLiteException: error code 5: database is locked 

Normalmente es difícil de simular, pero si u programa DataService para ejecutar por ejemplo cada 10 segundos (sólo para la demostración), u puede simular este error muy fácilmente.

Y mi pregunta es, ¿cómo manejar esto? He leído en documentos, que si hay dos eventos de escritura en el mismo tiempo, sólo primero se ejecutará, segundo será registrado como un error. Suena extraño, debe haber otras opciones, por ejemplo la segunda escritura esperaría hasta que termine la primera escritura. O tal vez otra solución? Tratando de leer documentos, pero parece que este elemento no está muy bien cubierto en google docs … Casi todas las informaciones que tengo, he encontrado en otras que las páginas oficiales.

PS: Esta es mi versión abreviada de mi clase DBHelper:

 public class DBHelper extends SQLiteOpenHelper { private static final String TABLE_NEWS = "News"; private static final String COL_ID = "id"; private static final String COL_TITLE = "title"; private static final String COL_ALERT = "alert"; public DBHelper(Context context) { super(context, "MY_DB_NAME", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE_NEWS + "(" + COL_ID + " TEXT PRIMARY KEY," + COL_TITLE + " TEXT," + COL_ALERT + " INTEGER" + ")"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NEWS); onCreate(db); } public void addRecords(ArrayList<NewsItem> items) { SQLiteDatabase db = this.getWritableDatabase(); for (int i = 0; i < items.size(); i++) { NewsItem item = items.get(i); ContentValues values = new ContentValues(); values.put(COL_ID, item.getId()); values.put(COL_TITLE, item.getTitle()); values.put(COL_ALERT, item.getAlertMe()); db.insert(TABLE_NEWS, null, values); } db.close(); } public int updateRecord(NewsItem item) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COL_ALERT_ME, item.getAlertMe()); int updated = db.update(TABLE_NEWS, values, COL_ID + " = ?", new String[] { item.getId() }); db.close(); return updated; } } 

2 Solutions collect form web for “La escritura concurrente a la base de datos android (de múltiples servicios)?”

SQLiteDatabase utilizar un objeto SQLiteDatabase único, a través de todos los subprocesos (y sus componentes de alojamiento) para obtener seguridad de subproceso. Haga que su DBHelper sea ​​un singleton, o use un ContentProvider , para lograr este efecto.

El ContentProvider fue creado por este motivo. Puede llamar desde varios subprocesos para operaciones de inserción / actualización / eliminación.

http://developer.android.com/reference/android/content/ContentProvider.html

Muchas personas sienten que sólo desea utilizar un ContentProvider si desea compartir datos. Ese es un gran beneficio de un ContentProvider , pero no es el único beneficio. El principal beneficio es que al usar un ContentProvider , Android administrará las conexiones de la base de datos para usted.

Este es un buen tutorial sobre proveedores de contenido

http://www.vogella.com/articles/AndroidSQLite/article.html

Nota: Aunque el JavaDoc para ContentProvider indica que es REQUERIDO para compartir datos, no significa que SE DEBE utilizar SOLAMENTE para compartir datos. En la documentación de Fundamentos de Aplicación, tiene esto que decir acerca de ContentProviders también.

Los proveedores de contenido también son útiles para leer y escribir datos que son privados para su aplicación y no compartidos. Por ejemplo, la aplicación de ejemplo Note Pad utiliza un proveedor de contenido para guardar notas.

http://developer.android.com/guide/topics/fundamentals.html#lcycles

  • SQLiteOpenHelper: la forma más rápida de ejecutar ~ 20k instrucciones?
  • Android obtener la imagen de disco de base de datos es malformado (código 11) error
  • Java - java.lang.IllegalStateException: No se pudo leer la fila 0, col -1 de CursorWindow
  • AsyncTask de Android y instancia de SQLite DB
  • ¿Cuál es el modo de subprocesamiento predeterminado de SQLite en Android?
  • SQLiteOpenHelper sincronización
  • ¿Cuándo debo llamar a close () en SQLiteOpenHelper utilizado por ContentProvider
  • Excepción fatal: error desconocido (código 14) no se pudo abrir la base de datos
  • Abra / cierre correctamente una base de datos con el patrón de diseño Singleton
  • SQLiteOpenHelper vs ContentProvider
  • Cursor finalizado sin cerrar antes () Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.