[英]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.