处理sqlite“数据库已锁定”安卓中的错误

发布于 2024-11-06 10:55:37 字数 1242 浏览 0 评论 0原文

我有一个应用程序,其数据库活动频繁。有时我会遇到 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. 我又开始看到这些错误;关于如何调试这个问题有什么建议吗?

感谢您的帮助, 朱利叶斯.

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 getWritingToDataBaseFlag() {
    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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若有似无的小暗淡 2024-11-13 10:55:37

我最终将 DbHelper (SQLiteOpenHelper) 的单个实例绑定到我的应用程序。通过这样进行所有调用,我永远不会遇到任何并发问题。

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.

因为看清所以看轻 2024-11-13 10:55:37

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

在 android 文档中说: isDbLockedByOtherThreads() 在 API 16 之后已被弃用。始终返回 false。不要使用此方法。

所以问题来自 isDbLockedByCurrentThread();

android API 介绍了该方法:

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

此方法的名称来源于与数据库的活动连接意味着线程持有数据库的实际锁定。如今,不再有真正的“数据库锁”,尽管线程如果无法获取数据库连接来执行特定操作可能会阻塞。

实际上,当你在android框架中的sqlite数据库中插入、删除、修改时,都是单线程的。这意味着当您使用两个或多个线程操作(插入、删除、修改)sqlitedatabase 时,它​​将抛出“数据库已锁定”错误;

但是你可以开启多线程对同一个sqlitedatabase进行排队,不会有任何问题

顺便说一句,如果你想在处理插入时排队;您应该

getWritableDatabase().enableWriteAheadLogging();

仅在 android 3.0 或更高版本上使用它;

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文