Android - 数据库已锁定

时间:2011-01-16 17:29:19

标签: android sqlite locking

我有一个可以将数据插入SQLite数据库的应用程序。每六十秒运行一次服务线程,检查条件是否为真,并在必要时发出警报。想想“日历”应用程序。

我有很多活动,他们引用了自己的SQLiteOpenHelper和他们自己的SQLiteDatabase对象。

该应用程序运行良好,但我决定需要一个主要的更新应用程序之一需要一个进度对话主题 - 这是另一个主题,但如果你能告诉我如何让旋转器旋转那就太好了。但它会显示。

但为了让它显示,我需要把它放在一个线程中。

创建这个线程,我开始在Log中获得大量“数据库被锁定”的消息。

我认为这个问题可能与我在后台运行每60秒运行一次的事实有关 - 即使它在视觉上只花了几秒钟来完成更新,所以我放置了主要的写入事务beginTransaction块中的updater函数。那是我唯一使用过的地方。

一切似乎都很好,但后来我开始收到更多关于数据库被锁定的虚假错误。

我鼓励我做一些整理,但似乎在我做了第一次beginTransaction之后,我想做的任何进一步的数据库修改都失败了,数据库被锁定的报告,尽管我确实调用了db.close。我甚至关闭数据库助手对象和光标只是为了安全起见。

我能够清除关于游标仍处于打开状态的大多数警告,例如

E/Database(  678): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

当一切都被关闭时,我无法弄清楚锁定数据库的原因。

然后我决定删除“beginTransaction”来稳定事物 - 我现在可以再次浏览我的程序。但我仍然得到一些随机锁定问题。

E/Database( 1304): Failure 5 (database is locked) on 0x26e5d8 when executing 'INSERT INTO

是否可以找出锁定数据库的内容?我可以看到关于锁的抱怨是什么,但不是什么锁定它。

处理这样的并发数据库更新/读取的最佳方法是什么?我已经阅读了很多关于synchronized和ContentProviders的内容,但我必须承认,这对我来说有点大。

关于“最佳”做事方式的任何指示?

我能找出锁定数据库的内容吗?

由于 西蒙

2 个答案:

答案 0 :(得分:2)

类NAME扩展了SQLiteOpenHelper

添加:

@Override
public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
      if (!db.isReadOnly()) {
          db.execSQL("PRAGMA foreign_keys=ON;");
          Cursor c = db.rawQuery("PRAGMA foreign_keys", null);
             if (c.moveToFirst()) {
                 int result = c.getInt(0);
             }
             if (!c.isClosed()) {
                    c.close();
             }        
      }
}

答案 1 :(得分:-2)

您可能希望查看最新版本的Berkeley DB作为选项。它提供了与SQLite3兼容的SQL API(以便您的应用程序保持不变),并提供更精细的锁定粒度,从而提高并发性。 Berkeley DB支持多个并发读写线程,以便同时主动访问数据库。您可以在our website找到有关Berkeley DB的更多信息。