【发布时间】:2018-03-01 21:08:15
【问题描述】:
我的应用程序的一个要求是允许用户完成多个步骤,然后在完成后根据每个步骤中的条目将值写入数据库。 UI 中的每个步骤都可能有助于需要写入数据库的操作。数据可能位于多个表中,并且与这些表中的不同行有关。如果任何数据库操作失败,那么整个操作都应该失败。
我最初考虑将所有数据加载到内存中,对其进行操作,然后简单地在每个可能的实体中调用更新方法(冲突策略为REPLACE),但内存中可能存在大量数据.
我认为我可以组装一个 List,其中显示中的每个 Fragment 贡献一个或多个 Completable,然后在 UI 流结束时使用 Completable.concat() 顺序执行这些。它看起来像下面这样:
Completable one = Completable.fromAction(() -> Log.w(LOG_TAG, "(1)")).delay(1, TimeUnit.SECONDS);
Completable two = Completable.fromAction(() -> Log.w(LOG_TAG, "(2)")).delay(2, TimeUnit.SECONDS);
Completable three = Completable.fromAction(() -> Log.w(LOG_TAG, "(3)")).delay(3, TimeUnit.SECONDS);
Completable four = Completable.fromAction(() -> Log.w(LOG_TAG, "(4)")).delay(3, TimeUnit.SECONDS);
Completable.concatArray(one, two, three, four)
.doOnSubscribe(__ -> {
mRoomDatabase.beginTransaction();
})
.doOnComplete(() -> {
mRoomDatabase.setTransactionSuccessful();
})
.doFinally(() -> {
mRoomDatabase.endTransaction();
})
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe();
Completables 实际上是 Room DAO 插入/更新/删除方法的包装器。我可能还会在完成后执行 UI 操作,这就是我在主线程上观察的原因。
当我执行这段代码时,我会得到这些日志:
W/MyPresenter: Begin transaction.
W/MyPresenter: (1)
W/MyPresenter: (2)
W/MyPresenter: (3)
W/MyPresenter: (4)
W/MyPresenter: Set transaction successful.
W/MyPresenter: End transaction.
W/System.err: java.lang.IllegalStateException: Cannot perform this operation because there is no current transaction.
W/System.err: at android.database.sqlite.SQLiteSession.throwIfNoTransaction(SQLiteSession.java:915)
W/System.err: at android.database.sqlite.SQLiteSession.endTransaction(SQLiteSession.java:398)
W/System.err: at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:524)
W/System.err: at android.arch.persistence.db.framework.FrameworkSQLiteDatabase.endTransaction(FrameworkSQLiteDatabase.java:88)
W/System.err: at android.arch.persistence.room.RoomDatabase.endTransaction(RoomDatabase.java:220)
W/System.err: at ...lambda$doTest$22$MyPresenter(MyPresenter.java:490)
为什么当我到达 doFinally 时交易就消失了?我也欢迎任何关于这种方法的质量或可行性的 cmet,因为我对 RxJava 和 Room 还很陌生。
【问题讨论】:
标签: android rx-java rx-java2 android-room