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.
- Is this the right way to go about getting around this issue?
- 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
精彩评论