Room @Transaction无法与Flowable配合使用

问题描述

我在数据源方法上使用@Transaction注释存在问题。在我看来,此注释无法正常工作。

我有一个带有DAO的普通会议室数据库

@Database(entities = [MyEntity::class],version = 1)
abstract class MyDatabase : RoomDatabase() {
    abstract fun myDao(): MyDao
}

@Dao
interface myDao {
    @Insert
    fun insertAll(list: List<MyEntity>)
    
    @Query("SELECT * FROM MyEntity")
    fun observe(): Flowable<List<MyEntity>>

    @Query("DELETE FROM MyEntity")
    fun clear()
}

当我持续执行clear()insertAll()

时,问题会出现在数据源中
class MyDataSource(database: MyDatabase) {
    private val myDao = database.myDao()

    @Transaction
    fun updateMyEntity(items: List<MyEntity>) {
        myDao.clear()
        myDao.insertAll(items)
    }

    fun observeMyEntity(): Flowable<List<MyEntity>> {
        return myDao.observe()
    }
}

当我致电updateMyEntity()时,在oberveMyEntity()订阅中得到两个结果。第一个结果是空列表,第二个结果是插入列表。我希望在将注解@Transaction添加方法updateMyEntity()时仅获得插入列表。在我的情况下,此注释不起作用吗?

我在文档中看到了以下信息,但不确定是否是我的情况。

如果查询是异步的(例如,返回{@link androidx.lifecycle.LiveData LiveData} 或RxJava {@code Flowable}),则在查询运行时(而不是在 该方法调用

将此注释放在{@link插入},{@ link更新}或{@link删除}方法上没有 影响,因为这些方法始终在事务内运行。同样,如果方法是 使用{@link Query}进行注释,但运行INSERT,UPDATE或DELETE语句,该语句将自动包装在事务中,并且此注释无效。

如果将database设置为属性并用clear()包装调用insertAll()database.runInTransaction { },问题就消失了。

解决方法

Transaction仅可用于Dao方法