Android数据库已锁定

use*_*844 34 android

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

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)
Run Code Online (Sandbox Code Playgroud)

Tod*_*ies 40

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

所以,我建议:

  • 您只能从一个访问数据库 SQLOpenHelper
  • 确保在完成数据库帮助程序后关闭所有数据库帮助程序实例
  • endTransaction()如果你没有成功设置它们(即如果你想要回滚它们),你确保你总是用它来结束交易,以防你使用交易
  • 您可以尝试使用OrmLite,我没有使用它,但我听到其他人对此赞不绝口.

  • 我将OrmLite的原始端口写入Android.你的第一个建议,只使用一个帮手,是一个很好的建议.你的第二个与你的第一个相矛盾."关闭所有数据库助手实例"意味着超过1.仅使用一个,总是!此外,您无需关闭助手连接.请看我的答案.最初我为OrmLite编写了复杂的引用计数代码,以帮助保持一个帮助程序,并在完成后关闭它,但事实证明,Sqlite"连接"只是文件句柄.系统会在转储进程时为您关闭它们. (9认同)
  • 是的,请参阅我的答案:http://stackoverflow.com/questions/2493331/what-are-the-best-practices-for-sqlite-on-android/3689883#3689883它链接到各种最佳实践示例. (6认同)
  • 是.我知道这听起来很糟糕.处理程序只是一个文件句柄.当过程死亡时它会关闭.SQLite不会腐败自己.至于仅在logcat中显示错误,对于"插入"而不是其他方法都是如此.这就是为什么你应该总是调用"insertOrThrow". (2认同)

Kev*_*gan 15

在整个应用程序中使用单个连接.看这里:

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


Kur*_*aum 8

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

有关更多信息,请查看此博文.


小智 5

我遇到了同样的问题,请尝试使用

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

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