我的应用程序有大量数据库活动。我不时会得到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();
}
}
这似乎已经有好一段时间了。
感谢您的帮助, 朱利。
答案 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