将"重试时间"添加到"数据库插入失败时单调"



我一直在试图弄清楚这一点,这对RXJava来说仍然是新的,但仍然不喜欢它,而是使用Livedata和协程,但无论如何。 我有这个:

Single.just(entity)
.map {
insertDb(it)
return@map it
}
.doOnSubscribe { Timber.d("Updating in database") }
.doOnSuccess { Timber.d("Added row in database") }
.doOnError { Timber.e(it, "Unable to insert object in db") }

fun insertDb(entity: T) {
try {
// basic update or insert database.begingTransaction() and endTransaction()
} catch (e: SQLiteDatabaseLockedException) {}
}

因此,当发生数据库锁定错误时,我想捕获它并使用带有 retryWhen(( 的 Single 重试插入。 我读到的例子非常复杂,不是我想要的。 并且不要担心锁定的数据库内容,这只是我如何捕获数据库错误的一个例子。

您可以使用PublishProcessor

val retryProcessor = PublishProcessor.create<Unit>()
Single.just("Entity")
.map { insertDB(it) }
.doOnError { Log.e(TAG, "Error") }
.retryWhen { retryProcessor }
.subscribe { entity -> Log.i(TAG, "Success: $entity") }

插入数据库:

fun insertDB(entity: String): String {
// Insert to DB
return entity
}

每当要执行重试时,请拨打PublishProcessor上的onNext

retryProcessor.onNext(Unit)

如果您只想在流中发生特定异常时重试,则retry(N)运算符在这里可能会更好。(其中 N 是要重试订阅的最大次数(。

Single.just(entity)
.map {
insertDb(it)
return@map it
}
.retry(1) { e -> e is SQLiteDatabaseLockedException }

您也不想在insertDb()函数中捕获异常,让它落入错误流中,以便您可以在retry函数中捕获它。

您可能还需要考虑从insertDb()返回SingleCompletable,然后像insertDb(entity).retry(1)...一样调用它,而不使用返回自身的尴尬map

您的insertDb()函数将变为如下所示:

fun <T> insertDb(entity: T): Completable {
return Completable.fromCallable {  
// Insert operation
}
}

最新更新