Android SQLite数据库SQLiteDatabaseLockedException异常分析及处理

 最近在Android项目中因为涉及到多线程访问数据库SQLite而出现SQLiteDatabaseLockedException异常,经过查找资料终于找到解决方法:避免数据库接口被多个线程同时访问。

具体措施有:

1、数据库接口采取单例模式

  1. public class DBOpenHelper extends SQLiteOpenHelper {  
  2.       
  3.     private static final String DB_FILENAME = "llhome.db";  
  4.     private static final int DB_VERSION = 1;  
  5.     private static DBOpenHelper helper = null;  
  6.       
  7.     public static DBOpenHelper getInstance(Context context){  
  8.         if (helper == null){  
  9.             synchronized (DBOpenHelper.class) {  
  10.                 if (helper == null){  
  11.                     DBOpenHelper temp = new DBOpenHelper(context);  
  12.                     helper = temp;  
  13.                 }  
  14.             }  
  15.         }  
  16.           
  17.         return helper;  
  18.     }  
public class DBOpenHelper extends SQLiteOpenHelper {
	
	private static final String DB_FILENAME = "llhome.db";
	private static final int DB_VERSION = 1;
	private static DBOpenHelper helper = null;
	
	public static DBOpenHelper getInstance(Context context){
		if (helper == null){
			synchronized (DBOpenHelper.class) {
				if (helper == null){
					DBOpenHelper temp = new DBOpenHelper(context);
					helper = temp;
				}
			}
		}
		
		return helper;
	}

2、所有访问数据的接口用synchronized加锁:

  1. boolean android.database.sqlite.SQLiteDatabase.isDbLockedByOtherThreads();  
  2.   
  3. boolean android.database.sqlite.SQLiteDatabase.isDbLockedByCurrentThread();  
boolean android.database.sqlite.SQLiteDatabase.isDbLockedByOtherThreads();

boolean android.database.sqlite.SQLiteDatabase.isDbLockedByCurrentThread();


3、光是给接口加锁还不行,因为 synchronized 关键词只能锁定程序块,但是我们真正需要锁的是数据库,好在SQLiteDataBase提供了两个接口,用于检测数据库当时是否被锁定:

所以我们在访问之前还需要增加判断,如果数据库当前被锁定,就等待一会再去访问。

  1. public synchronized void insert(InstallModel info) {  
  2.     while (db.isDbLockedByOtherThreads() || db.isDbLockedByCurrentThread()){  
  3.         Log.w(Tag, "insert === db is locked by other or current threads!");  
  4.         try {  
  5.             Thread.sleep(10);  
  6.         } catch (InterruptedException e) {  
  7.             e.printStackTrace();  
  8.         }  
  9.     }  
  10.       
  11.     db.execSQL("INSERT INTO install(pkg, pay, install, inApply, flag, attributes, id, introduction, name, smallPicUrl," +  
  12.             "bigPicUrl, categoryId, sourceUrl, pid, cid, built_in, applyMode) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?)",  
  13.             new Object[] {"" + info.getPkg(), "" + info.getPay(), "" + info.getInstall(), "" + info.getIsApply(), "" + info.getFlag(),  
  14.             "" + info.getAttributes(), "" + info.getId(), "" + info.getIntroduction(), "" + info.getName(), "" + info.getSmallPicUrl(),   
  15.             "" + info.getBigPicUrl(), "" + info.getCategoryId(), "" + info.getSourceUrl(), "" + info.getPid(), "" + info.getCid(),   
  16.             "" + info.getBuilt_in(), "" + info.getApplyMode()  
  17.             });  
  18. }  
	public synchronized void insert(InstallModel info) {
		while (db.isDbLockedByOtherThreads() || db.isDbLockedByCurrentThread()){
			Log.w(Tag, "insert === db is locked by other or current threads!");
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		db.execSQL("INSERT INTO install(pkg, pay, install, inApply, flag, attributes, id, introduction, name, smallPicUrl," +
				"bigPicUrl, categoryId, sourceUrl, pid, cid, built_in, applyMode) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?)",
				new Object[] {"" + info.getPkg(), "" + info.getPay(), "" + info.getInstall(), "" + info.getIsApply(), "" + info.getFlag(),
				"" + info.getAttributes(), "" + info.getId(), "" + info.getIntroduction(), "" + info.getName(), "" + info.getSmallPicUrl(), 
				"" + info.getBigPicUrl(), "" + info.getCategoryId(), "" + info.getSourceUrl(), "" + info.getPid(), "" + info.getCid(), 
				"" + info.getBuilt_in(), "" + info.getApplyMode()
				});
	}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值