美文网首页
SQLiteDatabaseLockedException: d

SQLiteDatabaseLockedException: d

作者: GinkWang | 来源:发表于2017-07-11 21:54 被阅读37次

    bug 复现

    两个 Fragment 对同一个数据库操作,然后是在这两个 Fragment 切换时出现的这个问题。当时觉得肯定是没有在第一个 Fragment 销毁时及时关闭数据库导致的。原理见此:

    文件数据库sqlite,同一时刻允许多个进程/线程读,但同一时刻只允许一个线程写。在操行写操作时,数据库文件被琐定,此时任何其他读/写操作都被阻塞,如果阻塞超过5秒钟(默认是5秒,能过重新编译sqlite可以修改超时时间),就报"database is locked"错误。

    但仔细排查后发现,并没有,数据库都已经关闭了,还是会出现这个问题。把数据库的操作写在基类中统一使用也还是不行。没办法了,只好到网上寻求解决方法。

    解决方法

    网上有几种解决方法,有通过 synchronized 关键字修饰数据库的,也有使用 isDbLockedByOtherThreads 方法判断数据库是否被锁的,还有种方法也是我最终选的解决方法,就是将 SQLiteOpenHelper 写成单例模式的。

    操作

    1. 在 SQLiteOpenHelper 中定义私有的静态对象

    private static DatabaseHelper instance;
    

    2. 为 SQLiteOpenHelper 提供一个单一的入口

    保证应用程序使用同一个对象操作数据库,不会因为对象不同而使同步方法失效

    public static DatabaseHelper getInstance(Context context){
       if(instance==null)
           instance=new DatabaseHelper(context);
       return instance;
    }
    

    3. 数据库中调用

    在数据库中通过 getInstance 方法获取 SQLiteOpenHelper 实例

    this.mDatabaseHelper = DatabaseHelper.getInstance(pContext);
    

    这样就能保证同一时间内只能有一个 SQLiteOpenHelper 访问 sqlite 数据库,避免同时有两个 SQLiteOpenHelper 访问 sqlite 报错的情况发生。

    参考

    http://www.voidcn.com/blog/u010002184/article/p-5987070.html

    相关文章

      网友评论

          本文标题:SQLiteDatabaseLockedException: d

          本文链接:https://www.haomeiwen.com/subject/itqvhxtx.html