英文:
Room @Transaction not working with Flowable
问题
我在使用@Transaction
注解在我的数据源方法上遇到了问题。在我的情况下,这个注解似乎不起作用。
我有一个常规的Room数据库和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()
订阅中会得到两个结果。第一个结果是空列表,第二个结果是插入的列表。我期望只得到插入的列表,因为我在updateMyEntity()
方法上添加了@Transaction
注解。这个注解在我的情况下不起作用吗?
我在文档中看到了以下信息,但我不确定是否适用于我的情况:
如果查询是异步的(例如返回{@link androidx.lifecycle.LiveData LiveData}或RxJava {@code Flowable}),事务会在查询运行时得到正确处理,而不是在方法调用时。
将此注解放在{@link Insert}、{@link Update}或{@link Delete}方法上没有任何影响,因为这些方法总是在事务内部运行。类似地,如果一个方法被{@link Query}注解标记,但运行的是INSERT、UPDATE或DELETE语句,它会自动被包装在一个事务中,这个注解不起作用。
如果将database
设置为属性,并使用database.runInTransaction { }
包装调用clear()
和insertAll()
,问题就会消失。
英文:
I have a problem with using @Transaction
annotation on my data source method. Looks like this annotation not working in my case.
I have a usual room database with 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()
}
Problem appears in my data source when I do consistently clear()
and 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()
}
}
When I call updateMyEntity()
, I get two results in my subscription on oberveMyEntity()
. The first result is empty list and the second one is inserted list. I expected to get only inserted list as I added annotation @Transaction
to method updateMyEntity()
. Is this annotation not working in my case?
I saw in docs the following information, but I am not sure is it my case or not.
> If the query is asynchronous (e.g. returns a {@link androidx.lifecycle.LiveData LiveData}
or RxJava {@code Flowable}), the transaction is properly handled when the query is run, not when
the method is called.
>
> Putting this annotation on an {@link Insert}, {@link Update} or {@link Delete} method has no
impact because those methods are always run inside a transaction. Similarly, if a method is
annotated with {@link Query} but runs an INSERT, UPDATE or DELETE statement, it is automatically wrapped in a transaction and this annotation has no effect.
The problem disappears if make database
a property and wrap calls clear()
and insertAll()
with database.runInTransaction { }
.
答案1
得分: 1
Transaction
只能用于 Dao
方法。
英文:
Transaction
can only be used for Dao
methods
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论