如何使用Room Db返回Rx单笔交易?

时间:2019-04-01 20:47:13

标签: android rx-java2 android-room

假设有一个Dao类,具有以下两种方法:

1)删除(项目:列表<项目>):可完成

2)插入(项目:列表<项目>):单个<列表<长>>

如何将它们链接到Dao类的以@delete方法开头的@transaction方法中,然后返回“ insert method”结果?

我想要一个带有这样签名的方法:

@交易 有趣的deleteAndInsert():Single <列表> {     ... }

5 个答案:

答案 0 :(得分:2)

我认为不可能。

我曾经尝试过,但出现编译时错误:

  

“用@Transaction注释的方法不得返回延迟/异步   返回类型io.reactivex.Single。由于交易是线程   受限,Room无法保证方法中的所有查询   实现在同一线程上执行,仅同步   允许使用@Transaction实现的方法。如果交易是   启动并完成线程更改,然后等待数据库   如果其他线程尝试执行   查询。这种限制可以防止这种情况的发生。”

答案 1 :(得分:2)

我假设您的主要目标是将deleteAndInsert()的返回类型设为Single

您只需进行一些修改即可实现

  • 首先通过使delete()insert()函数同步。
  • 由于@Transaction仅同步工作,因此我们需要创建另一个调用delete()insert()的函数。另外,请用@Transaction
  • 对此功能进行注释
  • 创建另一个新函数,该函数创建一个Single并调用上述函数。

abstract class SampleDao{
    protected abstract fun delete()
    protected abstract fun insert(items: List<Item>) : List<Long>

    @Transaction
    protected open fun deleteAndInsertSync(items: List<Item>): List<Long>{
        delete()
        return insert(items)
    }

    fun deleteAndInsert(items:List<Item>): Single<List<Long>>{
        return Single.create {
            it.onSuccess(deleteAndInsertSync(items))
        }
    }
}

答案 2 :(得分:0)

如果deleteinsert方法都标有注释,则它们正在事务中执行。因此,基本上,您不需要使用此批注标记您的deleteAndInsert方法。所以,比:

fun deleteAndInsert(items: List< Item >): Single<List<Long>> {
    return delete().andThan(insert(items))
}

答案 3 :(得分:0)

  • 使用@Transaction注释的方法不得返回延迟/异步返回类型io.reactivex.Single。由于事务受线程限制,Room无法保证方法实现中的所有查询都在同一线程上执行,因此仅允许@Transaction实现的同步方法。如果启动了事务并且完成了线程的更改并等待线程更改,那么如果其他线程尝试执行查询,则可能会发生数据库死锁。这种限制可以防止这种情况的发生。
  • 当我将代码反编译为Java时,会看到。

    public interface CustomerDao {
    @Transaction
    @NotNull
    List deleteAndCreate(@NotNull List var1);
    
    @Query("DELETE FROM customer")
    @NotNull
    Completable deleteAll();
    
    @Insert
    @NotNull
    List insertAll(@NotNull List var1);
    
    @Metadata(
       mv = {1, 1, 15},
       bv = {1, 0, 3},
       k = 3
    )
    public static final class DefaultImpls {
       @Transaction
       @NotNull
       public static List deleteAndCreate(CustomerDao $this, @NotNull List 
         users) 
       {
          Intrinsics.checkParameterIsNotNull(users, "users");
          $this.deleteAll();
          return $this.insertAll(users);
       }
    }
    }
    

答案 4 :(得分:0)

获取新数据ID

然后删除所有不在新数据中的项目

@Query("DELETE FROM product WHERE id NOT IN(:idsNewItems)")
    @Override
    public abstract void deleteOldItems(List<String> idsNewItems)

;