Kotlin Room withRepository 中的 Transaction 或 Dao 中的 @Transaction

Chr*_*lla 2 android android-room

我有一个关于 Room 和 it\xe2\x80\x99swithTransaction { }代码块与 Koin 结合的问题。

\n

我有一个存储库,需要同时访问几个 DAO。我想使用 a,withTransaction { }这样我就不会\xe2\x80\x99t 使 1 DAO 与其他 DAO 的引用变得混乱。\nI\xe2\x80\x99m 不确定要在我的存储库的构造函数中注入哪个对象。这withTransaction{ } 通过获取 RoomDatabase 来访问。但是,在我的存储库中拥有 RoomDatabase 意味着我可以访问连接到该 RoomDatabase 的所有 DAO。我\xe2\x80\x99m 不确定围绕此用例的最佳实践是什么。

\n

我应该使用withTransaction { }存储库中所有 DAO 都可访问的风险,还是应该将 DAO 放在存储库的构造函数中并将它们交给“ReviewDao”来处理每个插入?

\n

一个例子是这样的withTransaction { }

\n
class ReviewRepository(\n    private val roomDatabase: RoomDatabase\n) {\n    private val reviewDao = roomDatabase.reviewDao()\n    private val userDao = roomDatabase.userDao()\n\n    suspend fun saveReview(reviewResponse: ReviewResponse) {\n        roomDatabase.withTransaction {\n            reviewDao.insert(reviewResponse.getAsEntity())\n            userDao.insert(reviewResponse.user.getAsEntity())\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

和一个没有的例子withTransaction { }是这样的

\n
class ReviewRepository(\n    private val reviewDao : ReviewDao,\n    private val userDao : UserDao\n) {\n    suspend fun saveReview(reviewResponse: ReviewResponse) {\n        reviewDao.insertWithUser(reviewResponse.getAsEntity(), reviewResponse.user.getAsEntity(), userDao)\n    }\n}\n\n@Dao\ninterface ReviewDao {\n    @Transaction\n    suspend fun insertWithUser(review: Review, user: User, userDao: UserDao) {\n        insert(review)\n        userDao.insert(user)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Chr*_*lla 5

对我有用的解决方案是使用一个单独的类,该类在构造函数中接收数据库并提供withTransaction.

class TransactionProvider(
    private val db: AppDatabase
) {
    suspend fun <R> runAsTransaction(block: suspend () -> R): R {
        return db.withTransaction(block)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我可以将此类注入到我需要的存储库中,而无需向该存储库提供完整的数据库对象。