sqlite: Error Code : 5 (SQLITE_BUSY) (database is locked (code 5): , while compiling: PRAGMA journal_mode)
今天遇到了一个很奇怪的问题,登录完成后,程序会莫名crash, 报了下面的错误:
sqlite: Error Code : (SQLITE_BUSY) (database is locked (code ): , while compiling: PRAGMA journal_mode)
经过分析发现是数据库被locked,从而导致在调用
mDatabase = mDBHelper.getWritableDatabase();
时发生了crash, 而android上面同一时间向sqlite里写数据只允许有一个sqlite connection,所以发生了crash, 不过问题根源还是在数据库locked, 那么如何发生locked的呢?
仔细检查后发现:
private synchronized void copyTableFromAnonymousTable() { SQLiteDatabase db = openDatabase(); try { if (db.isOpen()) { db.execSQL("create table if not exists "+ FLIGHT_LOG_TABLE_NAME + "(id integer primary key autoincrement, " + ""+DBConfig.FLYING_LOG_USER_ID+" integer, "+ ""+DBConfig.FLYING_LOG_USER_NAME+" varchar(100), "+ ""+DBConfig.FLYING_LOG_HOME_LAT+" double, "+ ""+DBConfig.FLYING_LOG_HOME_LON+" double, "+ ""+DBConfig.FLYING_LOG_LAST_LAT+" double, "+ ""+DBConfig.FLYING_LOG_LAST_LON+" double, "+ ""+DBConfig.FLYING_LOG_LOCATION+" varchar(250), "+ ""+DBConfig.FLYING_LOG_CITY+" varchar(50), "+ ""+DBConfig.FLYING_LOG_DRONE_TYPE+" integer, "+ ""+DBConfig.FLYING_LOG_DRONE_TYPE_STR+" varchar(100), "+ ""+DBConfig.FLYING_LOG_DRONE_SSID+" varchar(150), "+ ""+DBConfig.FLYING_LOG_DRONE_SN+" varchar(150), "+ ""+DBConfig.FLYING_LOG_TAKEOFF_TIME+" long, "+ ""+DBConfig.FLYING_LOG_LANDING_TIME+" long, "+ ""+DBConfig.FLYING_LOG_DURATION+" long, "+ ""+DBConfig.FLYING_LOG_TAKEOFF_TIME_STR+" varchar(150), "+ ""+DBConfig.FLYING_LOG_RAW_OFFSET+" long, "+ ""+DBConfig.FLYING_LOG_APP_VERSION+" varchar(100), "+ ""+DBConfig.FLYING_LOG_FC_VERSION+" varchar(100), "+ ""+DBConfig.FLYING_LOG_RC_VERSION+" varchar(100), "+ ""+DBConfig.FLYING_LOG_CAM_VERSION+" varchar(100), "+ ""+DBConfig.FLYING_LOG_MAX_HEIGHT+" double, "+ ""+DBConfig.FLYING_LOG_MAX_SPEED+" double, "+ ""+DBConfig.FLYING_LOG_MAX_DISTANCE +" double, "+ ""+DBConfig.FLYING_LOG_TOTAL_MILEAGE+" double, "+ ""+DBConfig.FLYING_LOG_FLIGHT_STATUS+" double, "+ ""+DBConfig.FLYING_LOG_PLATFORM+" varchar(50), "+ ""+DBConfig.FLYING_LOG_EXTEND_DATA1+" varchar(100), "+ ""+DBConfig.FLYING_LOG_EXTEND_DATA2+" varchar(100), "+ ""+DBConfig.FLYING_LOG_EXTEND_DATA3+" varchar(100), "+ ""+DBConfig.FLYING_LOG_EXTEND_DATA4+" varchar(100)" +")"); db.beginTransaction(); db.execSQL("INSERT INTO "+FLIGHT_LOG_TABLE_NAME+" SELECT * FROM "+FLIGHT_DEFAULT_TABLE_NAME+""); db.setTransactionSuccessful(); db.endTransaction(); } } catch (Exception e) { e.printStackTrace(); } finally { closeDatabase(); }
db.execSQL("INSERT INTO "+FLIGHT_LOG_TABLE_NAME+" SELECT * FROM "+FLIGHT_DEFAULT_TABLE_NAME+"");
执行上述SQL语句时是有问题的,而这个问题被try catch 捕获掉了,但是:
db.endTransaction();
却没有被执行!后来将 db.endTransaction(); 移至finally 代码块中发现程序变好了。
以前一直觉得只要记得closeDatabase就好了,却没注意到不 end transaction 也会造成问题,在此记录一下,引以为诫。
关于如何unlock的问题
其实我发现数据库被Locked了之后的第一反应时是如何去unlock。不过很遗憾,我没有在现有的android API里找到类似于数据库lock/unlock的方法。不过android 倒是提供了一个
isDbLockedByCurrentThread() 这样的方法用于检测当前数据库是否有被lock, 网上很多的数据库打开方式都是类似于下列代码:
private synchronized SQLiteDatabase openDatabase() { if (mOpenCounter.incrementAndGet() == 1 || mDatabase == null) { mDatabase = mDBHelper.getWritableDatabase(); } return mDatabase; }
这种方式虽然貌似解决了多个 数据库connection的问题,但是个人以为还是不太完善,像我遇到的这种情况,最终crash就发生在
mDatabase = mDBHelper.getWritableDatabase();
这行代码里。因此个人以为保险起见,可以在上述代码之前添加一个诸如下列的代码:
private synchronized SQLiteDatabase openDatabase() { if (mOpenCounter.incrementAndGet() == 1 || mDatabase == null) { if (mDatabase == null) { mDatabase = mDBHelper.getWritableDatabase(); } else { while (mDatabase.isDbLockedByCurrentThread()) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } mDatabase = mDBHelper.getWritableDatabase(); } } return mDatabase; }
可能会更好点,个人看法。
sqlite: Error Code : 5 (SQLITE_BUSY) (database is locked (code 5): , while compiling: PRAGMA journal_mode)的更多相关文章
- sqlite:多线程操作数据库“database is locked”解决方法(二)
上一篇博客<sqlite:多线程操作数据库“database is locked”解决方法>通过注册延时函数的方法来处理数据库被锁的问题.此方法固然能解决问题,但是在多个线程向数据库写入大 ...
- sqlite:多线程操作数据库“database is locked”解决方法
1. 使sqlite支持多线程(不确定是否非加不可,暂且加上,以备后患) 可以在编译时/启动时/运行时选择线程模式,参考:http://www.cnblogs.com/liaj/p/4015219.h ...
- sqlite遇到database is locked问题的完美解决
这两天在项目中用大强度大频率的方法测试时遇到sqlite报database is locked的问题,分析下来原因是sqlite对数据库做修改操作时会做(文件)锁使得其它进程同一时间使用时会报该错误( ...
- SQLITE报错database is locked的解决办法
用firedac连接SQLITE数据库,空间tdbedit绑定字段name,如下语句修改其值时报错. procedure TForm1.Button3Click(Sender: TObject);be ...
- 解决SQLite database is locked
前些时候,同事在站点服务端使用SQlite存储一些临时数据,但是在多人并发的时候Sqlite会抛出异常:The database file is locked , database is locked ...
- sqlite 报错:database is locked
在sqlite批量添加数据时,报错:database is locked. 解决办法:将db路径由相对路径设置为绝对路径.
- dpkg: error: dpkg status database is locked by another process 解决方法
使用dpkg -i/apt命令安装,报错: ------------------------------------------------------------- dpkg: error: dpk ...
- 解决SQLite中的 database is locked
前些时候,同事在站点服务端使用SQlite存储一些临时数据,但是在多人并发的时候Sqlite会抛出异常:The database file is locked , database is locked ...
- SQLITE 多进程查询出错database is locked
程序比较简单: 父进程查询数据库A表,没有更新操作 子进程同时查询数据库A表,查询出来的内容更新B表. 两个进程都放到while(1)循环中,速度慢的话就是2S执行一次就没有错,执行的速度快的话就会报 ...
随机推荐
- TL Cop
第一讲 研发技术型人才的特点 一.为何要重视技术与研发技术管理 1.中国技术型企业近十年的发展路线图以及经验教训 2.技术还是营销:中国企业的痛 3.名家论技术与研发技术管理 二.研发技术人才的特点 ...
- <图形图像,动画,多媒体> 读书笔记 --- 音效
音频多媒体文件主要是存放音频数据信息,音频文件在录制的过程中把声音信号,通过音频编码,变成音频数字信号保存到某种格式文件里.在播放过程中在对音频文件解码,解码出的信号通过扬声器等设备就能够转成音波.音 ...
- fisheye Error occurred during initialization of VM Could not reserve enough space for object heap 问题解决!
参考文章:https://answers.atlassian.com/questions/9397/not-enough-heap-space-to-run-fisheye fisheye下载好了之后 ...
- web前端工程师在移动互联网时代里的地位问题 为啥C/S系统在PC端没有流行起来,却在移动互联网下流行了起来 为啥移动端的浏览器在很多应用里都是靠边站,人们更加倾向于先麻烦自己一下,下载安装个客户端APP
web前端工程师在移动互联网时代里的地位问题 支付宝十周年推出了一个新产品:支付宝的十年账单,我也赶个时髦查看了一下我的支付宝十年账单,哎,感慨自己真是太屌丝了,不过这只是说明我使用淘宝少了,当我大规 ...
- k8s实战之Service
一.概述 为了适应快速的业务需求,微服务架构已经逐渐成为主流,微服务架构的应用需要有非常好的服务编排支持,k8s中的核心要素Service便提供了一套简化的服务代理和发现机制,天然适应微服务架构,任何 ...
- wxss解析
一.概述 wxss是样式语言,用于描述wxml组件样式: 在css基础上扩展而来: 1.尺寸单位: rpx, rem 2.支持样式导入 @import语句导入外联样式表 note: 微信小程序一般使 ...
- 【Java】详解菜单组件
在这篇文章中,笔者会介绍Java图形界面编程中菜单组件的用法.关于菜单组件,因为java存在AWT编程和Swing编程,所以菜单组件也存在AWT菜单和Swing菜单.因为Swing组件使用的比较多,所 ...
- 【Spring】基于SpringMVC的图片验证码功能实现
后台实现代码: ImgController.java 文件 package cn.shop.controller; import java.awt.Color; import java.awt.Fon ...
- 算法中的 log 到底是什么?
之前一直不解为何算法中经常会看到 log 今天看<数据结构与算法分析 Java 语言描述>(第 3 版)2.4.3 节 求最大子序列和的分治算法实现时才注意到原因 翻看第 29 页的最后一 ...
- ARGB和PARGB
原文链接: http://blog.csdn.net/lnwaycool/article/details/8610313 ARGB和PARGB是针对32位图像而言的,Windows下图像可以是1位.4 ...