我正在试用 Kotlin 的 Arrow 库 Either
对象来处理项目中的异常。
到目前为止,我的经验还可以,但我正在努力寻找一种方法来处理与 Either
的交易。 - 特别是回滚。在 Spring 扔一个 RuntimeException
是导致事务回滚的可靠方法。但是,通过使用 Either
不会抛出异常,因此不会触发回滚。
您可以将此视为一个多方面的问题:
Either
适用于真 Exception
处理?不是替代控制流,我的意思是程序流需要停止的真正错误情况。 transactionManager
以编程方式 - 你能避免吗? Either
? 最佳答案
你的一些问题没有直接的答案,但我会尽力:D
- Is Either appropriate for true Exception handling. Not alternative control flow, I mean true error situations where the flow of the program needs to stop.
Spring 使用异常来模拟触发器回滚,因此在这种情况下,您需要遵守 Spring 的机制。
如果您更喜欢使用
Either
API,您可能可以使用 Either<RuntimeException, A>
包装 Spring 的基于异常的 API。或 Either<E, A>
一。所以回答你的问题,
Either
适用于异常处理。但是,通常您只会捕获您感兴趣的异常并使用您自己的错误域对其进行建模。意外的异常或您无法解决的异常通常会被允许冒泡。
- If so, how do you achieve rollbacks with them?
包装的伪代码示例
transaction: () -> A
与 transactionEither: () -> Either<E, A>
.class EitherTransactionException(val result: Either<Any?, Any?>): RuntimeException(..)
fun transactionEither(f: () -> Either<E, A>): Either<E, A> =
try {
val result = transaction { f() }
when(val result) {
is Either.Right -> result
is Either.Left -> throw EitherTransactionException(result)
}
} catch(e: EitherTransactionException) {
return e.result as Either<E, A>
}
现在你应该可以使用 Either<E, A>
同时保持 Spring 基于异常的模型完好无损。If the answer to question 2. is by using the transactionManager programatically - could you avoid that?
我在避免问题的同时回答了问题 2。或者,通过使用
transactionManager
以编程方式,您可以避免必须抛出该异常并恢复该值。I'll squeeze this one in, how do you avoid nesting Eithers
Either#flatMap
或 either { }
链接相关值 (Either<E, A>)
+ (A) -> Either<E, B>
Either#zip
组合独立的值。 Either<E, A>
+ Either<E, B>
+ (A, B) -> C
. 关于spring - Kotlin 的 Arrow <Exception, X> 和交易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67299007/