从多个线程访问的SQLite DB

时间:2011-06-03 09:38:47

标签: android sqlite

请考虑以下事项:我已Service,其在AsyncTask中写入数据库。我的Activity从DB读取数据(为简单起见,考虑UI线程)。我使用SQLiteOpenHelper访问数据库。我在Application onCreate()中创建单个实例,然后在服务和活动中获取它。我是否有可能让我的DB被锁定?#39;?以前,我使用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 This可能是解决方案,但不确定如何使用它。

5 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:2)

我打赌:这不安全。

为了处于更安全的位置,您应该使用SQL事务。从beginTransaction()beginTransactionNonExclusive()开始,以endTransaction()结束。 Like shown here

答案 2 :(得分:1)

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

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任务,它运行正常。 我希望是解决问题的正确方法。

还有其他建议???

答案 3 :(得分:0)

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

  

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

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

答案 4 :(得分:0)

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