频道栏目
首页 > 数据库 > SQL Server > 正文
SQLiteDatabaseLockedException: database is locked 解决方法
2017-07-13 10:32:09      个评论    来源:边缘狂欢手册  
收藏   我要投稿

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 报错的情况发生。

点击复制链接 与好友分享!回本站首页
上一篇:详解SQLServer连接(内连接、外连接、交叉连接)
下一篇:SQL中使用WithAs处理层级关系小记
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训

版权所有: 红黑联盟--致力于做实用的IT技术学习网站