1

我有一个项目,其中包含一组负责各自数据库表的类。

每个表管理类都包含 CRUD 方法,这些方法遵循获取连接、运行 crud 操作、关闭连接的模式:

public class PersonManager {

    SQLiteDatabase db;
    DbAdapter dbAdapter; //This is a subclass of SQLiteOpenHelper

    public void addPerson(Person person)
    {
        ContentValues contentValues = new ContentValues();
        contentValues.put("email", person.email);
        contentValues.put("first_name", person.firstName);

        db = dbAdapter.getWritableDatabase();
        db.insert("person", null, contentValues);
        db.close();
    }

    ...other crud/utility methods omitted...
}

现在我正在通过 onUpgrade() 升级我的数据库,我遇到了数据库锁定问题。

确切的错误消息如下:

CREATE TABLE android_metadata failed
Failed to setLocale() when constructing, closing the database
android.database.sqlite.SQLiteException: database is locked

看来 onUpgrade 要么是为了:

1 run db.execSQL() calls or
2 use helper classes that use onUpgrade()'s SQLiteDatabase rather than their own

使用我的表管理类来迁移 onUpgrade() 中的数据比使用 db.execSQL() 语句要容易得多,或者重写我所有的 CRUD 方法以采用 onUpgrade() 的 SQLiteDatabase。

我是否正确设置了我的数据库访问权限?如果上面的代码遵循正确的模式,我应该怎么做才能解决这个问题?

谢谢!

4

2 回答 2

3

这是你的问题:

db = dbAdapter.getWritableDatabase();

当您在 onUpgrade() 中时,您必须使用 onUpgrade() 为您提供的 SQLiteDatabase 句柄。因此,您的解决方案是重写您的 addPerson 函数以获取更多参数 - SQLiteDatabase 句柄:

public void addPerson(Person person, SQLiteDatabase db) {...}

如果您需要从项目的其他地方调用 addPerson(),则保留当前的 ​​addPerson(Person person) 函数,让它执行 db = dbAdapter.getWritableDatabase() 调用,并将 db 传递给 addPerson( )。

于 2015-03-18T17:23:50.700 回答
1

我没有得到任何答案,所以我在开发者视频群聊中询问。

根据 Android 开发人员环聊团队的说法,onUpgrade 仅用于结构更改,而不是真正用于数据迁移/操作。

于 2012-06-22T19:15:47.980 回答