简体   繁体   English

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

[英]How to handle transactions with SQLite and Android?

I try to include transactions in my application because writing in database is very slow and I saw here and here that transactions are a solution but they are still very confusing to me. 我尝试将事务包含在我的应用程序中,因为在数据库中写入速度非常慢,我在这里这里都看到事务是一种解决方案,但它们仍然使我感到困惑。

I have Schedule objects that contains an object LineStation , and I want to write them in database using transactions. 我有包含对象LineStation Schedule对象,并且我想使用事务在数据库中写入它们。

Here, the method addSchedules in my class ScheduleDAO , that writes all schedules in database. 在这里,我的类ScheduleDAO的方法addSchedules将所有计划写入数据库。 It contains only one transaction. 它仅包含一笔交易。

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();
}

And this is, the method addLineStation in my class LineStationDAO that saves the object LineStation given. 这是,该方法addLineStation在我班上LineStationDAO ,节省对象LineStation给出。 It's called by addSchedules and doesn't contain transaction because it is "nested" in the addSchedules transaction. 它由addSchedules调用,并且不包含事务,因为它在addSchedules事务中“嵌套”。

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();
}

The LineStation insert implies an SQLiteDatabaseLockedException (database is locked -code 5). LineStation插入表示SQLiteDatabaseLockedException (数据库已锁定-代码5)。 What I have done wrong, please? 请问我做错了什么? Thanks. 谢谢。

The problem is that a database transaction cannot exist across multiple database connections. 问题是数据库事务不能跨多个数据库连接存在。 In the addLineStation method, you are opening a second database connection, when you should be using the one created in addSchedules. 在应该使用addSchedules中创建的数据库连接时,在addLineStation方法中,您将打开第二个数据库连接。

You need to pass the SQLiteDatabase db object down to the addLineStation method like this: 您需要像这样将SQLiteDatabase db对象传递给addLineStation方法:

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

and change this: 并更改此:

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)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM