Android 如何使用房间数据库返回Rx单笔交易?

Android 如何使用房间数据库返回Rx单笔交易?,android,rx-java2,android-room,Android,Rx Java2,Android Room,假设有一个具有以下两种方法的Dao类: (一) 我认为这是不可能的 我曾经尝试过它,但我得到了一个编译时错误,它说: “用@Transaction注释的方法不能返回延迟/异步 返回类型io.reactivex.Single。因为事务是线程 受限和受限空间不能保证方法中的所有查询 实现在同一线程上执行,仅同步 @允许使用事务实现的方法。如果事务是 启动并更改线程,然后等待数据库 如果额外的线程试图执行 查询。此限制可防止此类情况发生。” 我假设您的主要目标是将返回类型deleteAndInsert

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

(一)


我认为这是不可能的

我曾经尝试过它,但我得到了一个编译时错误,它说:

“用@Transaction注释的方法不能返回延迟/异步 返回类型io.reactivex.Single。因为事务是线程 受限和受限空间不能保证方法中的所有查询 实现在同一线程上执行,仅同步 @允许使用事务实现的方法。如果事务是 启动并更改线程,然后等待数据库 如果额外的线程试图执行 查询。此限制可防止此类情况发生。”


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

您只需稍加修改即可实现这一点

  • 首先,使
    delete()
    insert()函数同步
  • 由于
    @Transaction
    只能同步工作,因此我们需要创建另一个调用
    delete()
    insert()
    的函数。另外,用
    @Transaction
  • 创建另一个新函数,该函数创建一个
    单个
    ,并调用上述函数

抽象类SampleDao{
受保护的抽象趣味删除()
受保护的抽象趣味插入(项目:列表):列表
@交易
受保护的open fun deleteAndInsertSync(项目:列表):列表{
删除()
返回插入(项目)
}
乐趣删除和插入(项目:列表):单个{
返回Single.create{
it.onSuccess(删除和插入同步(项目))
}
}
}

如果
delete
insert
方法用注释标记,则它们在事务中执行。因此,基本上不需要使用此注释标记
delete和insert
方法。因此,比:

fun deleteAndInsert(items: List< Item >): Single<List<Long>> {
    return delete().andThan(insert(items))
}
fun deleteAndInsert(项目:列表):单个{
返回delete().和(插入(项))
}
  • 用@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);
       }
    }
    }
    
获取新数据的ID

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

@Query("DELETE FROM product WHERE id NOT IN(:idsNewItems)")
    @Override
    public abstract void deleteOldItems(List<String> idsNewItems)
@Query(“从id不在(:idsNewItems)中的产品中删除”)
@凌驾
公共摘要void deleteOldItems(列表idsNewItems)

)

我认为他们不会在同一笔交易中执行。
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))
        }
    }
}
fun deleteAndInsert(items: List< Item >): Single<List<Long>> {
    return delete().andThan(insert(items))
}
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);
   }
}
}
@Query("DELETE FROM product WHERE id NOT IN(:idsNewItems)")
    @Override
    public abstract void deleteOldItems(List<String> idsNewItems)