Android中的并发SQLite访问

时间:2014-05-15 14:01:19

标签: android sqlite concurrency

让我开始说我确实阅读了搜索中出现的大多数主题,例如: SQLite and concurrency

然而,我不相信提议使用单个SQLiteDatabase的解决方案 是解决问题的方法。

我按照https://github.com/dmytrodanylyk/dmytrodanylyk/blob/gh-pages/articles/Concurrent%20Database%20Access.md文章执行了实施模式。

我仍然会遇到错误。这是我的情景:

我在UI上运行主应用程序。它确实调用数据库R / W功能。 我也有AsyncTasks,我正在启动,他们也在另一个线程上访问DB。

方案: 后台任务从Web获取数据并尝试将其存储在SQLite中。数据大小各不相同,最多可插入1000个。为了加快速度,我将其包装成交易。当bg线程写入数据库时​​,我在主线程中从数据库中读取一些内容。这就是我得到的:

  

W / SQLiteConnectionPool:数据库的连接池   '/data/data/com.hhh/databases/data.db'无法授予   连接到线程1(主)与标志0x5 30.001001秒。

这几乎就像锁定一样。我不明白SQLite如何管理并发“internaly”,但从我看到的确有问题。

拥有DB对象的单例并没有真正帮助,即使它被序列化了所以呢?函数将从2个不同的线程中等待,但最后两个调用者都将获得SQLiteDatabase并进入“问题”。我不相信像这样的代码可以解决问题:

public synchronized SQLiteDatabase openDatabase(String purpose)
    {
        if (mOpenCounter.incrementAndGet() == 1)
        {
            // Opening new database
            mDatabase = mDatabaseHelper.getWritableDatabase();
        }

        Log.d(LOG_TAG, "Database open counter: " + mOpenCounter.get() + " for " + purpose);
        return mDatabase;
    }

更进一步 - 我看看如何跟踪给出的数量和在最后一次引用上关闭数据库有多少帮助。为什么我关心数据库是否关闭?

我想要的是对数据库的真正串行访问。问题是..我如何实现这一目标?假设我有100个不同的函数在不同的线程上运行,它们都可以访问数据库。如何确保2不同时运行?我理解潜在的性能并发症,但这没关系。所有查询和数据库访问都运行得非常快,即使让后台线程首先访问数据库也不会对UI造成太大损害。

我对Java不太满意,但在C#中我可以使用

lock(some object) { .... } 

并将此结构放入我的所有数据访问位置。这将确保如果我在内部进行DB内容 - 其他呼叫者将等待。

有什么建议吗?评论?我想要的东西可能不是理想而是简单。理想的是一个代码,我可以区分我是否希望RO操作没有序列化和写操作序列化。但是从我看到的情况来看,甚至RO操作也可能在DB处于交易过程中时引起问题。

1 个答案:

答案 0 :(得分:0)

您可以使用synchronized块:

public void someMethod() {
    synchronized (someObject) {
        ...
    }
}