【问题标题】:Android Database LockedAndroid 数据库锁定
【发布时间】:2011-12-17 07:48:37
【问题描述】:

我收到以下错误。那么如何解锁我的数据库呢?

10-28 08:43:26.510: ERROR/AndroidRuntime(881): FATAL EXCEPTION: Thread-11
10-28 08:43:26.510: ERROR/AndroidRuntime(881): android.database.sqlite.SQLiteDatabaseLockedException: database is locked
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983)
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956)
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021)
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:742)
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149)
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at com.aa.me.vianet.dbAdapter.DbAdapter.open(DbAdapter.java:25)
10-28 08:43:26.510: ERROR/AndroidRuntime(881):     at com.aa.me.vianet.services.NotificationManagerThread.run(NotificationManagerThread.java:49)

【问题讨论】:

  • 1.确保您仅在同一文件上使用单个 SQLiteOpenHelper。 2. 确保一次只有一个线程在使用您的 SQLiteDatabase。

标签: android


【解决方案1】:

我认为您忘记关闭数据库,或者当您尝试写入数据库时​​,另一个线程正在写入数据库。 SQLite 在写入数据库时​​锁定数据库,以避免在另一个实体同时尝试写入同一个数据库时损坏。 Android,只会在log cat中显示错误,而您提供的查询将被遗忘...

所以,我建议:

  • 您只能从一个SQLOpenHelper 访问数据库
  • 确保在完成所有数据库助手实例后关闭它们
  • 您确保始终使用endTransaction() 结束交易,如果您未将它们设置为成功(即,如果您想回滚),以防您使用交易
  • 您可以尝试使用OrmLite,我没用过,但我听说这里的其他人对此赞不绝口。

【讨论】:

  • 我把OrmLite的原始移植写到Android上。你的第一个建议,只使用一个助手,是很好的建议。你的第二个与你的第一个矛盾。 “关闭数据库助手的所有实例”意味着不止1个。只使用一个,总是!!!此外,您不需要关闭助手连接。请看我的回答。最初,我为 OrmLite 编写了复杂的引用计数代码,以帮助保持一个助手处于活动状态,并在完成后关闭它,但事实证明,Sqlite“连接”只是文件句柄。系统会在转储进程时为您关闭它们。
  • 嗨,Kevin,这是否意味着您永远不必关闭数据库处理程序?
  • 是的。我知道这听起来很糟糕。处理程序只是一个文件句柄。当进程终止时它将关闭。 SQLite 不会自我损坏。至于只在logcat中显示错误,“插入”是这样,其他方法则不然。这就是为什么你应该总是调用“insertOrThrow”。
  • 这方面有什么好的教程吗,我从来没有遇到过关于 Android 中 SQLite 的综合教程 :-( 谢谢 :D
  • 是的,请在此处查看我的答案:stackoverflow.com/questions/2493331/… 它链接到各种最佳实践示例。
【解决方案2】:

在整个应用中使用单一连接。见这里:

http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection

【讨论】:

  • 你能修复这个链接吗?如何通过单个连接处理多线程访问?
  • 我使用了这种方法,但在我的情况下不起作用请看看我的问题link is here...
  • 您正在使用正在做奇怪事情的外部 API。我猜你需要调整你如何调用他们的api。 UrbanAirship 不太可能经常发生这种事故。
【解决方案3】:

发生这种情况的原因是您一次只能打开一个与数据库的连接(这是为了防止在修改数据库时出现竞争条件)。我猜你从不同的线程多次连接到你的数据库?解决这个问题的最简单方法是为您的数据库创建一个ContentProvider 前端。这将能够处理来自多个线程的查询。

欲了解更多信息,请查看此blogpost

【讨论】:

  • 博文链接失效,新链接为touchlab.co/blog/android-sqlite-locking
  • 不是,“新链接”也不是,但现在博客帖子似乎可以工作,尽管“新链接”仍然断开。
  • 我在多进程应用程序中使用数据库。并且只有少数用户面临这个问题。你能告诉我这个问题的解决方案是什么。数据库被锁定(代码 5):,编译时:PRAGMA journal_mode
【解决方案4】:

我遇到了同样的问题,试试这个

   db.beginTransactionNonExclusive();
   try {
       //do some insertions or whatever you need
       db.setTransactionSuccessful();
   } finally {
       db.endTransaction();
   }

我尝试使用 db.beginTransaction 但它锁定了 bd

【讨论】:

    【解决方案5】:

    我遇到了类似的错误。我的问题是我不小心给了两个帮助类的数据库同名,因此它们最终同时访问了同一个数据库。因此,请确保您没有访问具有多个帮助器类的单个数据库。

    【讨论】:

      【解决方案6】:

      我在尝试通过ContentResolver 访问我的数据库时遇到了同样的问题,而我已经打开了一个直接的SQLiteDatabase 连接(事务需要)。

      我通过更改我的代码顺序解决了这个问题,所以ContentResolver 的东西在我的直接SQLiteDatabase 连接打开之前完成。

      我还删除了一些代码,因此我不再关闭我的直接SQLiteDatabase

      值得一读this answer,因为它提供了许多其他有用的指导。

      【讨论】:

        【解决方案7】:

        在我的情况下,这个错误是由于常见错误造成的。最初,我的 SQLite 数据库由来自 MySQL 的 JsonArray 接收的数据填充。在 SQLite 数据库中添加附加列后,发生了类似的错误。很简单,我忘了在 MySQL 数据库中添加相应的列.. :)

        【讨论】:

          【解决方案8】:

          当我们遇到如下错误时我们可以做什么。

          android.database.sqlite.SQLiteDatabaseLockedException: 数据库是 锁定

          数据库锁意味着数据库正在与其他一些线程一起执行任务,同时,其他线程正在执行该任务。

          所以我的解决方案是:

          您必须在执行查询或在数据库中进行事务之前检查 像这样。

          if(!sqLiteDatabase.isDbLockedByCurrentThread() && !sqLiteDatabase.isDbLockedByOtherThreads()) 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-08-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多