开发者

Dealing with sqlite 'database is locked' errors in Android

I have an application which has times of heavy database activity. From time to time I used to get SQLite 'database is locked' errors leading to SQLiteExceptions. Whie I have tried to use:

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

before using save or insert but this hasn't been successful. So, I have set up the following in a class eg. MyApplication which extends Application like so:

private AtomicBoolean writingToDataBaseFlag = new AtomicBoolean(false);

with an accessor:

public AtomicBoolean getWrit开发者_Go百科ingToDataBaseFlag() {
    return writingToDataBaseFlag;
}

and any time I want to perform an insert or save I do something like this:

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();
    }
}

This seems to have worked well for quite a while.

  1. Is this the right way to go about getting around this issue?
  2. I have started to see these errors again; is there any advice on how to debug this issue?

Thanks for any help, Julius.


I have ended up having a single instance of my DbHelper (SQLiteOpenHelper) tied to my Application. By making all calls through this I never have any concurrency issues.


all right, I have access to information . and find one interesting article about the thread Operate the database.

In the android docs's said : isDbLockedByOtherThreads() is deprecated after API 16. Always returns false. Do not use this method.

so the problem come from isDbLockedByCurrentThread();

The android API said about the method :

Returns true if the current thread is holding an active connection to the database.

The name of this method comes from a time when having an active connection to the database meant that the thread was holding an actual lock on the database. Nowadays, there is no longer a true "database lock" although threads may block if they cannot acquire a database connection to perform a particular operation.

Actually,when you insert , delete , modify in the sqlitedatabase in the android framework it all about single thread . it means when you use two or more thread Operate(insert , delete , modify) the sqlitedatabase it will throw 'database is locked' errors;

But you can open multithreading to queue the same sqlitedatabase , it won't have any problem

By the way , if you want queue when you deal the insert ; you should use

getWritableDatabase().enableWriteAheadLogging();

it only work on android 3.0 or higher;

maybe you should read this article(If you can read chinese , haha): http://tech.techweb.com.cn/thread-621414-1-1.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜