database is locked

原文连接:http://blog.csdn.net/zsg2063/article/details/21014721?utm_source=tuicool&utm_medium=referral

这几天写线程操作,其中涉及到多线程操作数据库的问题。一个读线程不停地在读取数据库数据,另外一个Service不断地采集传感器数据并写入。在手机运行过程中出现上述错误。网络上提及到这个问题不在少数,但是给出的解决方案我基本都看不懂。。

最后找到师兄,介绍了单例模式,大概敲了几行,就解决了。

具体的单例模式还是要深入研究,我就简单把我个人理解的意思写下来吧。

像SQLiteDatabase(或者SQLiteDBHhelper)的实例,只能有一个。也就是操作数据库的链接(Connection)只能有一个,否则就会出现上述错误。

还有很多人提及到ContentProvider,现在的知识水平还并不理解这个东西是做什么用的。

无论是SQLite这种轻量级数据库,还是SQL Server这种大型的数据库,本身都是“线程安全的”,也就是说,像加锁、解锁、防止读脏数据这一类的数据库基本约束都已经由SQLite数据库本身保证,Java或android程序猿是无法左右其是否加解锁的,并且,如果你的程序正确,无论操作频率多高,都是可以运行,宁可崩溃,也不会出现“脏数据”的情况。

那么我的程序中出现了两个线程,由于SQLite数据库自身的安全约束,导致线程读写数据库冲突,某线程无法读写另一线程已经加锁的数据库。

解决的办法就是使用单例模式来严格控制SQLiteDatabase的实例,也就是只能实例化一个SQLiteDatabase对象,无论多少个线程,都只用这一个SQLiteDatabase(或者是DBHelpler)来读写线程。这样共用一个数据库链接就不会产生多个链接同时修改数据的问题了。

以上纯属个人理解。

[java] view plaincopy

  1. public class MotionAnalysisDatabase extends SQLiteOpenHelper{
  2. <span style="color:#ff0000;">   public MotionAnalysisDatabase(Context context) {
  3. // 数据库名为MotionAnalysisDatabase,版本号1
  4. super(context, "MotionAnalysisDatabase", null, 1);
  5. }
  6. private volatile static MotionAnalysisDatabase uniqueInstance;
  7. public static MotionAnalysisDatabase getInstance(Context context) {
  8. if (uniqueInstance == null) {
  9. synchronized (MotionAnalysisDatabase.class) {
  10. if (uniqueInstance == null) {
  11. uniqueInstance = new MotionAnalysisDatabase(context);
  12. }
  13. }
  14. }
  15. return uniqueInstance;
  16. }
  17. </span>
  18. @Override
  19. public void onCreate(SQLiteDatabase db) {
  20. String createAccTable = "CREATE TABLE acc_table" + " (" + AccTable.ACC_ID
  21. + " INTEGER primary key autoincrement, " + AccTable.DATE + " TEXT, " +
  22. AccTable.ACCX + " float, "+ AccTable.ACCY + " float, "+AccTable.ACCZ + " float, "+ AccTable.FLAG + " INTEGER);";
  23. System.out.println("创建运动加速度数据表的语句" + createAccTable);
  24. db.execSQL(createAccTable);
  25. }
  26. @Override
  27. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  28. // TODO Auto-generated method stub
  29. db.execSQL("DROP TABLE IF EXISTS acc_table");
  30. }
  31. }

在线程中,要是引用MotionAnalysisDatabase,可以这么写:

[java] view plaincopy

  1. private MotionAnalysisDatabase mDatabase;
  2. private SQLiteDatabase db;

[java] view plaincopy

  1. mDatabase = MotionAnalysisDatabase.getInstance(AccDataCollectorService.this);
  2. db = mDatabase.getWritableDatabase();

这样再引用,就没有在报这个错误了。

时间: 2024-10-02 00:22:41

database is locked的相关文章

转发 FMDB多线程下&quot;is currently in use&quot; 或者 &quot;database is locked&quot; 问题

FMDB多线程下"is currently in use" 或者 "database is locked" 问题 问题一: "is currently in use" 出现的场景是这样的,多线程操作数据库,每个线程都使用了FMDatabase实例(注意没有使用FMDatabaseQueue). 问题二:“database is locked"出现的场景是这样的,多线程操作数据库,每个线程各自创建了FMDatabaseQueue实例操作数

SQLITE报错database is locked的解决办法

用firedac连接SQLITE数据库,空间tdbedit绑定字段name,如下语句修改其值时报错. procedure TForm1.Button3Click(Sender: TObject);begin fdquery.Edit; fdquery.FieldByName('name').AsString:='test2'; fdquery.post;   //执行到这里报错 [FireDAC][Phys][SQLite] ERROR: database is locked. 换成refres

sqlite:多线程操作数据库“database is locked”解决方法(二)

上一篇博客<sqlite:多线程操作数据库“database is locked”解决方法>通过注册延时函数的方法来处理数据库被锁的问题.此方法固然能解决问题,但是在多个线程向数据库写入大量数据的情况下,延时会拖慢进度. 想出方法二: 1. 创建一个链表,链接如下格式的结构体,线程1,线程2,线程3......不直接改写数据库,而是把sql语句插入链表中: typedef struct { uint8_t *buf; uint32_t len; } sqlItem_t; 2. 创建一个独立的线

FMDB多线程下&quot;is currently in use&quot; 或者 &quot;database is locked&quot; 问题

问题一: "is currently in use" 出现的场景是这样的,多线程操作数据库,每个线程都使用了FMDatabase实例(注意没有使用FMDatabaseQueue). 问题二:“database is locked"出现的场景是这样的,多线程操作数据库,每个线程各自创建了FMDatabaseQueue实例操作数据库,或者一个线程创建FMDatabaseQueue实例来操作,而另外的线程创建了FMDatabase实例来操作. 解决:FMDB多线程操作数据库,必须使

解决SQLite database is locked

前些时候,同事在站点服务端使用SQlite存储一些临时数据,但是在多人并发的时候Sqlite会抛出异常:The database file is locked , database is locked,而且这个是在客户生产环境下提示出来的,开发环境很难重现,同事实在没辙,竟然想发动所有研发同事通过操作软件重现问题,我只能呵呵了.既然是Sqlite的原因,直接写个小程序测试下sqlite不就行了,而且就算重现了,难不成要改Sqlite源码... Sqlite的特点: 简单(simple):SQLi

解决SQLite中的 database is locked

前些时候,同事在站点服务端使用SQlite存储一些临时数据,但是在多人并发的时候Sqlite会抛出异常:The database file is locked , database is locked,而且这个是在客户生产环境下提示出来的,开发环境很难重现,同事实在没辙,竟然想发动所有研发同事通过操作软件重现问题,我只能呵呵了.既然是Sqlite的原因,直接写个小程序测试下sqlite不就行了,而且就算重现了,难不成要改Sqlite源码... Sqlite的特点: 简单(simple):SQLi

使用FMDB多线程访问数据库,及database is locked的问题

今天终于解决了多线程同时访问数据库时,报数据库锁定的问题,错误信息是: Unknown error finalizing or resetting statement (5: database is locked) 最后通过FMDatabaseQueue解决了这个问题,本文总结一下: FMDatabase不能多线程使用同一个实例 多线程访问数据库,不能使用同一个FMDatabase的实例,否则会发生异常.如果线程使用单独的FMDatabase实例是允许的,但是同样有可能发生database is

java.lang.UnsupportedOperationException: Database is locked

今天在部署jira系统的时候报错: java.lang.UnsupportedOperationException: Database is locked 原因分析:造成这个错误的原因有很多,如果你是在安装一个新的数据库,那么有可能是entityengine.xml配置错误引起的,也有可能是你的数据库需要修复,也就是说你的数据库出了问题. 解决方法: 必须要删除这个三个:remove three things-- .jira-home.lock .bundled-plugins/ and .os

svn和NetBeans一起使用造成svn老是死锁, database is locked

其实我一直没发现,又一次我以为需要写些前端吧NetBeans关了,使用HBuilder写vue,因为内存只有8G,乱七八糟的一些东西一开,只剩20%左右,我就把 NetBeans关了,发现更新svn的时候,不会出现一大堆文件的,老是出现database is locked的情况了,等我写完vue页面,在去写php接口的时候,因为需要编译vue,我吧一些无用的更新删除,更新到最新的时候, 又出现老是database is locked 解决办法就比较简单了,你需要需要先更新svn,在开NetBea

dpkg: error: dpkg status database is locked by another process 解决方法

https://i.cnblogs.com/EditPosts.aspx?opt=1使用dpkg -i/apt命令安装,报错: ------------------------------------------------------------- dpkg: error: dpkg status database is locked by another process 无法获得锁 /var/lib/apt/lists/lock - open ------------------------