如何使用 SQLite 和 Android 处理事务?

How to handle transactions with SQLite and Android?

我尝试在我的应用程序中包含事务,因为写入数据库非常慢,我看到 here and here 事务是一种解决方案,但它们仍然让我感到困惑。

我有 Schedule 个包含对象 LineStation 的对象,我想使用事务将它们写入数据库。

在这里,我的 class ScheduleDAO 中的方法 addSchedules 将所有计划写入数据库。它只包含一笔交易。

public void addSchedules(ArrayList<Schedule> schedulesList) {
    SQLiteDatabase db = this.dh.getWritableDatabase();
    db.beginTransactionNonExclusive();

    for (Schedule schedule : schedulesList) {
        ContentValues values = new ContentValues();

        // insert linestation
        LineStationDAO.getLineStationDAO().addLineStation(schedule.getLineStation());

        values.put(/*...*/);
        /* ... */

        db.insert(DatabaseHandler.TABLE_SCHEDULE, null, values);
    }

    db.setTransactionSuccessful();
    db.endTransaction();
    db.close();
}

这是我的 class LineStationDAO 中的方法 addLineStation 保存给定对象 LineStation 的方法。它由 addSchedules 调用并且不包含交易,因为它在 addSchedules 交易中是 "nested"。

public void addLineStation(LineStation lineStation)  {
    SQLiteDatabase db = this.dh.getWritableDatabase();
    ContentValues values = new ContentValues();

    values.put(/*...*/);
    /* ... */

    db.insert(DatabaseHandler.TABLE_LINE_STATION, null, values); // database is locked (code 5)
    db.close();
}

LineStation 插入意味着 SQLiteDatabaseLockedException(数据库已锁定 - 代码 5)。 请问我做错了什么?谢谢。

问题是一个数据库事务不能跨多个数据库连接存在。在 addLineStation 方法中,您打开了第二个数据库连接,而您应该使用在 addSchedules 中创建的连接。

您需要像这样将 SQLiteDatabase 数据库对象传递给 addLineStation 方法:

LineStationDAO.getLineStationDAO().addLineStation(db, schedule.getLineStation());

并更改此:

public void addLineStation(SQLiteDatabase db, LineStation lineStation)  {
    ContentValues values = new ContentValues();

    values.put(/*...*/);
    /* ... */

    db.insert(DatabaseHandler.TABLE_LINE_STATION, null, values); // database is no longer locked (code 5)
}