考虑下面的Room DAO
@Dao
public abstract class JobDao {
@Insert
public abstract long insert( Job v );
@Update
public abstract int update( Job v );
@Insert
public abstract long insertPerson( Person p );
@Update
public abstract int updatePerson( Person p );
@Transaction
public void insertNetJobs( List<NetJob> list ) {
Timber.d("--- insert page start");
for( NetJob j : list ) {
if ( updatePerson( j.getPerson() ) == 0 ) {
insertPerson( j.getPerson() );
}
insert( j.getJob() );
}
Timber.d("--- insert page end");
}
}
根据文档,方法中标记有@Transaction的任何东西都会在单个事务中运行。但实际上,它为整个方法insertNetJobs运行一个事务,并为每次调用updatePerson、insertPerson、insert运行内部事务。所以日志看起来是这样的
D/JobDao: ---- insert page start
D/SQLiteDatabase: beginTransaction()
D/SQLiteDatabase: endTransaction()
beginTransaction()
D/SQLiteDatabase: endTransaction()
beginTransaction()
D/SQLiteDatabase: endTransaction()
beginTransaction()
........................
D/SQLiteDatabase: endTransaction()
beginTransaction()
D/SQLiteDatabase: endTransaction()
beginTransaction()
D/SQLiteDatabase: endTransaction()
D/JobDao: ---- insert page end
因此,insertNetJobs方法的运行速度非常慢。是否有可能使用唯一的一个事务来运行此方法?
发布于 2018-08-07 23:54:54
好了,我知道问题出在哪里了。如果有人有类似的问题,这里有一个解释。实际问题出在更新查询上。它花了大约20毫秒来执行它。
这段代码:
@Update
public abstract int updatePerson( Person p );
生成以下查询:
UPDATE OR ABORT `sw_person` SET `id` = ?,`id_s` = ?,`id_lang` = ?,`name` = ? WHERE `id` = ?
此查询更新person表的pk,但在其他表中,此键被用作fk,这会导致在这些表中进行查找。遗憾的是,“房间”更新了更新查询中的pk,可能解决方案是手动编写查询。
发布于 2018-08-07 12:29:25
尝尝这个
roomDB.runInTransaction(new Runnable() {
@Override
public void run() {
Timber.d("--- insert page start");
for( NetJob j : list ) {
if ( updatePerson( j.getPerson() ) == 0 ) {
insertPerson( j.getPerson() );
}
insert( j.getJob() );
}
Timber.d("--- insert page end");
}
});
https://stackoverflow.com/questions/51715200
复制相似问题