从多个线程访问的SQLite DB

请考虑以下内容:我有Service ,它在AsyncTask写入DB。 我的Activity从DB读取数据(为简单起见,考虑UI线程)。 我使用SQLiteOpenHelper访问数据库。 我在Application onCreate()中创建单个实例,然后在服务和活动中获取它。 我有可能让我的数据库’死锁’吗? 以前,我使用ContentProvider进行此类操作。 虽然它基于使用单个SQLiteOpenHelper实例,但我决定通过排除ContentProvider来简化我的项目。

考虑代码:

 public class App extends Application { private OpenHelper openHelper; @Override public void onCreate(){ super.onCreate(); openHelper=new OpenHelper(); } public OpenHelper getHelper(){ return openHelper; } } 

在活动中:

 OpenHelper helper=(App)getApplication().getHelper(); SQLiteDatabase db=helper.getReadableDatabase(); // Do reading 

在Serice内部,在单独的线程中:

 OpenHelper helper=(App)getApplication().getHelper(); SQLiteDatabase db=helper.getWritableDatabase(); //Do writing 

它会安全吗?

UPD 这可能是解决方案,但不确定如何使用它。

迟到,迟到的答案。 你完全没事。 实际上,这是实现它的正确方法。 请参阅我的博客文章: http : //touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection/ 。 在这里挖掘我的个人资料。 很多这方面的例子。 除非您在应用程序之外共享数据,否则ContentProvdier只需要很多开销而且不需要。 事务处理可以加快速度并且(显然)提高一致性,但不是必需的。

只需在您的应用中使用一个SqliteOpenHelper即可。

我打赌:这不安全。

为了处于更安全的位置,您应该使用SQL事务。 从beginTransaction()beginTransactionNonExclusive()开始,并以endTransaction() 。 如此处所示

这是我的解决方案,我创建了一个类和一个私有静态对象来同步所有数据库访问

 public class DBFunctions { // ... private static Object lockdb = new Object(); /** * Do something using DB */ public boolean doInsertRecord(final RecordBean beanRecord) { // ... boolean success = false; synchronized (lockdb) { // ... // // here ... the access to db is in exclusive way // // ... final SQLiteStatement statement = db.compileStatement(sqlQuery); try { // execute ... statement.execute(); statement.close(); // ok success = true; } catch (Exception e) { // error success = false; } } return success; } 

}

我尝试使用ASYNC任务,它工作正常。 我希望是解决问题的正确方法。

任何其他建议???

好问题。 我的第一个想法是不安全。 但是,根据SQLite文档 ,SQLite可以在3种模式下使用。 默认模式为“序列化”模式:

序列化。 在序列化模式下,SQLite可以被多个线程安全地使用而没有任何限制

所以我假设这是在Android上以序列化模式编译的。

在我寻找其他东西的时候看到这个。 这个问题看起来像使用ContentProvider可以有效地解决。 这样,Activity和Service都可以使用内容提供程序,这将解决Db争用问题。