android对多线程对数据库,Android上的SQLite数据库,多线程,锁定和帐户同步

我正在尝试获得一个对我的sqlite数据库的多线程访问没有失败的模式.另外,让我疯狂的是我无法重现这个问题.

我有一个使用数据库的应用程序,还有Android帐户和Android同步来同步我的应用程序的数据.我的猜测是,当两者同时发生时,它会崩溃.我遇到了很多错误:

* android.database.sqlite.sqliteDatabaseLockedException: database is locked

* android.database.sqlite.sqliteDatabaseLockedException: database is locked (code 5)

* android.database.sqlite.sqliteDatabaseLockedException: error code 5: database is locked

* android.database.sqlite.sqliteDatabaseLockedException: database is locked (code 5):,while compiling: PRAGMA journal_mode

* android.database.sqlite.sqliteDiskIOException: disk I/O error (code 778)

* android.database.sqlite.sqliteException: Failed to change locale for db '/data/data/net.bicou.redmine/databases/redmine.db' to 'en_US'. \n Caused by: android.database.sqlite.sqliteDatabaseLockedException: database is locked (code 5)

也许并非所有这些都与相同的根本原因有关,但我有点迷失.

我有的是:

>一个抽象基类,DbAdapter,由想要管理单个表的子类扩展

>一个管理sqlite数据库的类,名为DbManager,包含一个Lock

现在,用户有一个不是单身的DbManager版本.我打算让DbManager成为单例,以便所有线程共享同一个对象.这不应该是一个问题,因为据我所知,后台同步和应用程序共享相同的过程.

这是课程(只有相关部分):

public abstract class DbAdapter {

Context mContext;

protected DbManager mDbManager;

sqliteDatabase mDb;

public static final String KEY_ROWID = "_id";

public DbAdapter(final Context ctx) {

mContext = ctx;

}

public DbAdapter(final DbAdapter other) {

mContext = other.mContext;

mDb = other.mDb;

mDbManager = other.mDbManager; // removed with singleton version

}

public synchronized DbAdapter open() throws sqlException {

if (mDb != null) {

return this;

}

mDbManager = new DbManager(mContext); // currently in production

mDbManager = DbManager.instance(mContext); // currently investigating this singleton solution

try {

mDb = mDbManager.getWritableDatabase();

} catch (final sqlException e) {

L.e("Unable to open DB,trying again in 1 second",e);

try {

Thread.sleep(1000);

} catch (final InterruptedException e1) {

L.e("Could not wait 1 second " + e1);

}

mDb = mDbManager.getWritableDatabase();// This may crash

}

return this;

}

public synchronized void close() {

mDbManager.close();

mDbManager = null;

mDb = null;

}

}

需要处理数据库表的类将扩展DbAdapter,并实现select,insert,delete等方法.

public class DbManager extends sqliteOpenHelper {

private static final String DB_FILE = "db";

private static final int DB_VERSION = 15;

Context mContext;

Lock mLock = new ReentrantLock();

// Currently in prod

public DbManager(final Context context) {

super(context,DB_FILE,null,DB_VERSION);

mContext = context;

}

// singleton version will make this constructor private and add:

private static DbManager mInstance;

public static synchronized DbManager instance(Context context) {

if (instance == null) {

instance = new DbManager(context);

}

return instance;

}

@Override

public sqliteDatabase getWritableDatabase() {

mLock.lock();

return super.getWritableDatabase();

}

@Override

public void close() {

super.close();

mLock.unlock();

}

@Override

public void onCreate(final sqliteDatabase db) {

// ...

}

@Override

public void onUpgrade(final sqliteDatabase db,final int oldVersion,final int newVersion) {

// ...

}

private void createTables(final sqliteDatabase db,final String[] statements) {

for (final String sql : statements) {

try {

db.execsql(sql);

} catch (final Exception e) {

L.e("Unable to create table: " + sql,e);

}

}

}

}

好的,现在,问题.

>我的锁是否正确实施?我真的很陌生,我不知道ReentrantLock是不是一个好选择,如果我在适当的时候锁定/解锁

>我的同步方法是否正确实施?我的意思是,我已将synchronized关键字放在我不希望被并发线程中断的方法周围.这是正确的吗?你可以就我的同步使用提出建议吗?

>我该如何重现这个问题?我创建了一个测试,它使用3个线程对数据库进行并发读/写访问,并使用一些Thread.sleep来确保每个线程的db打开/关闭重叠,但它不会崩溃.这真是烦我,我不认为有很多人有这个问题,所以我不知道如何重现.

>我的DbAdapter DbManager技术选择是个好主意吗?有更好的模式吗?

>让DbManager成为单身人士是个好主意吗?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值