Kotlin 的箭头要么<例外,X>和交易 [英] Kotlin&#39;s Arrow Either&lt;Exception, X&gt; and transactions

查看:32
本文介绍了Kotlin 的箭头要么<例外,X>和交易的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

解决方案

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

<块引用>

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

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

如果您更喜欢使用 Either API,您可能可以使用 EitherEither一.

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

<块引用>

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

包装transaction的伪代码示例:() ->AtransactionEither: () ->.

class EachTransactionException(val 结果:Either): RuntimeException(..)fun transactionEither(f:()->Either):Either=试试{val 结果 = 交易 { f() }当(val 结果){是.对 ->结果是要么.左->抛出任何事务异常(结果)}} catch(e:EitherTransactionException){将 e.result 返回为任一}

现在您应该能够使用 Either,同时保持 Spring 基于异常的模型完好无损.

<块引用>

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

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

<块引用>

我把这个挤进去,你如何避免嵌套Eithers

  • 使用 Either#flatMapeither { } 链接相关值 (Either) + (A) ->
  • 使用Either#zip 组合独立的值.Either + Either + (A, B) ->C.

I am trialing the use of Kotlin's Arrow library Either object to handle exceptions within a project.

My experience with it thus far has been OK, but I'm struggling to find a way to handle transactions with Either - and specifically rollbacks. In Spring throwing a RuntimeException is a sure way to cause a transaction to rollback. However, by using Either no exception is thrown and thus no rollback is triggered.

You can view this as a multifaceted question:

  1. 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.
  2. If so, how do you achieve rollbacks with them?
  3. If the answer to question 2. is by using the transactionManager programatically - could you avoid that?
  4. I'll squeeze this one in, how do you avoid nesting Eithers?

解决方案

Some of your questions don't have straight forward answers but I'll do my best :D

  1. 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 uses exceptions to model trigger rollbacks, so in that case you need to abide by Spring's mechanisms.

If you prefer to use an Either API, you can probably wrap the exception based API of Spring with an Either<RuntimeException, A> or Either<E, A> one.

So to answer your question, Either is appropriate for exception handling. However, typically you'll only catch the exceptions you're interessted and model them with your own error domain. Unexpected exceptions, or exceptions you cannot resolve are often allowed to bubble trough.

  1. If so, how do you achieve rollbacks with them?

Pseudo code example of wrapping transaction: () -> A with 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>
  }

And now you should be able to use Either<E, A> while keeping the exception based model of Spring intact.

If the answer to question 2. is by using the transactionManager programatically - could you avoid that?

I answered question 2 while already avoiding it. Alternatively, by using the transactionManager programatically you could avoid having to throw that exception and recovering the value.

I'll squeeze this one in, how do you avoid nesting Eithers

  • Use Either#flatMap or either { } to chain depenent values (Either<E, A>) + (A) -> Either<E, B>
  • Use Either#zip to combine independent values. Either<E, A> + Either<E, B> + (A, B) -> C.

这篇关于Kotlin 的箭头要么<例外,X>和交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆