在Android中处理sqlite'数据库被锁定'错误

时间:2011-05-12 05:47:24

标签: android sqlite

我的应用程序有大量数据库活动。我不时会得到SQLite'数据库被锁定'错误导致SQLiteExceptions。我试图使用的是:

if((!db.isDbLockedByCurrentThread())&&(!db.isDbLockedByOtherThreads())) {

在使用保存或插入之前,但这没有成功。所以,我在课堂上设置了以下内容,例如。扩展应用程序的MyApplication如下:

private AtomicBoolean writingToDataBaseFlag = new AtomicBoolean(false);

带有访问者:

public AtomicBoolean getWritingToDataBaseFlag() {
    return writingToDataBaseFlag;
}

任何时候我想执行插入或保存我都会这样做:

boolean succeeded = false;
while(!succeeded) {
   if(application.getWritingToDataBaseFlag().compareAndSet(false, true)) {
       if((!db.isDbLockedByCurrentThread())&&(!db.isDbLockedByOtherThreads())) {
           if(!activity.isFinishing()) {
               set_id(db.insert(SDIGENRE, SDIID, cv));
           }
       }
       application.getWritingToDataBaseFlag().compareAndSet(true, false);
       succeeded = true;
    } else {
    // Wait 100 millis
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

这似乎已经有好一段时间了。

  1. 这是解决这个问题的正确方法吗?
  2. 我已经开始再次看到这些错误;有关如何调试此问题的建议吗?
  3. 感谢您的帮助, 朱利。

2 个答案:

答案 0 :(得分:1)

我最终将我的DbHelper(SQLiteOpenHelper)的一个实例绑定到我的应用程序。通过完成所有调用,我从来没有任何并发​​问题。

答案 1 :(得分:0)

好的,我可以访问信息。并找到一篇关于线程的有趣文章操作数据库。

在android docs中说:isDbLockedByOtherThreads()在API 16之后被弃用。总是返回false。不要使用这种方法。

所以问题来自isDbLockedByCurrentThread();

android API说的方法:

如果当前线程持有与数据库的活动连接,则返回true。

此方法的名称来自与数据库建立活动连接的时间,这意味着该线程正在对数据库进行实际锁定。如今,不再存在真正的“数据库锁定”,尽管如果线程无法获取数据库连接以执行特定操作,则可能会阻塞。

实际上,当您在android框架中的sqlitedatabase中插入,删除,修改它所有关于单个线程。它意味着当你使用两个或多个线程操作(插入,删除,修改)sqlitedatabase时它会抛出'数据库被锁定'错误;

但是你可以打开多线程来排队相同的sqlitedatabase,它不会有任何问题

顺便说一句,如果你在处理插入时想要队列;你应该使用

getWritableDatabase().enableWriteAheadLogging();

它只适用于Android 3.0或更高版本;

也许你应该读这篇文章(如果你能读中文,哈哈):http://tech.techweb.com.cn/thread-621414-1-1.html