Android Room DAO如何在单个事务中运行几种DAO方法?

时间:2018-08-06 20:29:13

标签: java android transactions android-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的工作非常缓慢。是否有可能仅使用一个事务来运行此方法?

2 个答案:

答案 0 :(得分:1)

尝试一下

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

<div class="alert alert-secondary alert-dismissible" id="delAlbumAlert">
  <span><strong>Delete Album!</strong> Select the album(s) you want to delete.</span>
  <button type="button" class="close" aria-label="Close" onclick="return handleOptions($('#btnDeleteAlbum'));">
    <span aria-hidden="true" style="color:black;">&times;</span>
  </button>
</div>

答案 1 :(得分:0)

好的,我想出了问题所在。万一有人有类似问题,这里有一个解释。实际问题是更新查询。执行它大约需要20毫秒。

此代码:

   @Update
   public abstract int updatePerson( Person p );

生成以下查询:

UPDATE OR ABORT `sw_person` SET `id` = ?,`id_s` = ?,`id_lang` = ?,`name` = ? WHERE `id` = ?

此查询更新人员表的pk,但在其他表中,此键用作fk,导致在这些表中查找。遗憾的是,“房间”在更新查询中更新了pk,解决方案可能是手动编写查询。