我可以使用RxJava保存数据:
override fun put(note: Note): Observable<Note> {
validateNote(note)
return Observable.just(note)
.doOnNext { dbKeeper.startTransaction() }
.doOnNext { storeHashtags(note) }
.doOnNext { storeImages(note) }
.flatMap { notesDataStore.put(notesMapper.transform(note)) }
.map { notesMapper.transform(it) }
.doOnNext { dbKeeper.setTransactionSuccessful() }
.doOnUnsubscribe { dbKeeper.endTransaction() }
}
然后我像这样使用这个方法:
notesManager.put(note)
.switchMap { notesManager.getHashtags() }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {view.setHashtags(it) }
doOnUnsubscribe
从未调用getHashtags()
尝试从startTransaction()
锁定的数据库中进行SELECT。死锁,嘿。
好的。我们将doOnUnsubscribe(...)
替换为doOnTerminate(...)
。
override fun put(note: Note): Observable<Note> {
validateNote(note)
return Observable.just(note)
.doOnNext { dbKeeper.startTransaction() }
.doOnNext { storeHashtags(note) }
.doOnNext { storeImages(note) }
.map { notesMapper.transform(note) }
.flatMap { notesDataStore.put(it) }
.map { notesMapper.transform(it) }
.doOnNext { dbKeeper.setTransactionSuccessful() }
.doOnTerminate { dbKeeper.endTransaction() }
}
但是,如果Observable
subscriber.unsubscribe()
被{{1}}中断,现在交易将不会关闭。
你可以推荐什么来解决我的情况?
其他信息: 我使用一个writableDb实例来写/读数据。
答案 0 :(得分:1)
我认为这不适合Rx;我的建议是使用通常的try-finally进行事务处理(原谅Java):
Observable<Note> put(Note note) {
return just(note)
.doOnNext(n -> {
validateNote(n);
dbKeeper.startTransaction();
try {
storeHashtags(n);
storeImages(n);
notesDataStore.put(notesMapper.transform(n));
dbKeeper.setTransactionSuccessful();
} finally {
dbKeeper.endTransaction();
}
});
}
编辑:也许这更有用:
fun <T> withTransaction(sourceObservable: Observable<T>): Observable<T> {
val latch = AtomicInteger(1)
val maybeEndTransaction = Action0 {
if (latch.decrementAndGet() == 0) {
endTransaction()
}
}
return Observable.empty<T>()
.doOnCompleted { startTransaction() }
.mergeWith(sourceObservable)
.doOnNext { setTransactionSuccessful() }
.doOnTerminate(maybeEndTransaction)
.doOnUnsubscribe(maybeEndTransaction)
}
像这样使用:
override fun put(note: Note): Observable<Note> {
return Observable.just(note)
.doOnNext { validateNote(note) }
.doOnNext { storeHashtags(note) }
.doOnNext { storeImages(note) }
.flatMap { notesDataStore.put(notesMapper.transform(note)) }
.map { notesMapper.transform(it) }
.compose { withTransaction }
}
它将确保交易完成一次;请注意不要在原始可观察链中切换线程(除非您的事务管理器可以处理它,或者您修改了调度程序以将新线程与现有事务相关联)。