Kotlin的Arrow<Exception,X>和交易

我正在尝试使用 Kotlin 的 Arrow 库Either对象来处理项目中的异常。

到目前为止,我的经验还不错,但我正在努力寻找一种方法来处理事务Either,特别是回滚。在 Spring 中抛出 aRuntimeException是导致事务回滚的可靠方法。但是,通过使用Either不会引发异常,因此不会触发回滚。

您可以将此视为一个多方面的问题:

  1. 是否Either适合真实Exception处理?不是替代控制流,我的意思是程序流需要停止的真正错误情况。
  2. 如果是这样,您如何通过它们实现回滚?
  3. 如果问题 2. 的答案是以transactionManager编程方式使用- 你能避免这种情况吗?
  4. 我把这个挤进去,你如何避免嵌套Either

回答

你的一些问题没有直接的答案,但我会尽力:D

  1. 是否适用于真正的异常处理。不是替代控制流,我的意思是程序流需要停止的真正错误情况。

Spring 使用异常来模拟触发器回滚,因此在这种情况下,您需要遵守 Spring 的机制。

如果您更喜欢使用EitherAPI,您可以将 Spring 的基于异常的 API 包装为一个Either<RuntimeException, A>Either<E, A>一个。

所以回答你的问题,Either适合做异常处理。但是,通常您只会捕获您感兴趣的异常并使用您自己的错误域对其进行建模。意外的异常或您无法解决的异常通常会被允许冒泡。

  1. 如果是这样,您如何通过它们实现回滚?

包装的伪代码示例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 基于异常的模型完好无损的同时使用。

如果问题 2. 的答案是以编程方式使用 transactionManager - 你能避免这种情况吗?

我在避免问题的同时回答了问题 2。或者,通过以transactionManager编程方式使用 ,您可以避免抛出该异常并恢复该值。

我把这个挤进去,你怎么避免嵌套Eithers

  • 使用Either#flatMapeither { }链接相关值(Either<E, A>)+(A) -> Either<E, B>
  • 使用Either#zip相结合的独立价值。Either<E, A>+ Either<E, B>+ (A, B) -> C

以上是Kotlin的Arrow&lt;Exception,X&gt;和交易的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>