代码之家  ›  专栏  ›  技术社区  ›  bca

无例外地回滚事务

  •  0
  • bca  · 技术社区  · 4 年前

    我想从服务层向控制器返回这两种类型,而不是抛出异常,但当我从服务层抛出异常时,JPA的@Transactional只会回滚,而服务层最初有@Transactional注释。

    所以我尝试实现以下包装器

    @Component
    class Foo {
        fun <A, B> run(f: () -> Either<A, B>): Either<A, B> {
            val bar = Bar()
            try {
                return bar.run(f)
            } catch (t: Bar.BarException) {
                return t.result as Either<A, B>
            }
        }
    }
    
    @Transactional
    class Bar {
        data class BarException(val result: Any) : Throwable()
    
        fun <A, B> run(f: () -> Either<A, B>): Either<A, B> {
            val result = f()
            if (result.isError())
                throw BarException(result)
            return result
        }
    }
    

    我的想法是,我将把一个带有DB操作的lambda传递给Foo,Foo将把它传递给@Transactional Bar,如果出现错误(或者。Left),Bar将把它作为异常抛出,Foo将捕获它,将其展开,并作为其中之一返回服务。

    例如

    fun serviceMethod() {
      Foo.run {
        repository.find
         --business logic--
        repository.save
      }
    }
    

    但我仍然收到一个错误,表明我没有在事务中工作。

    注意:我知道编程事务管理,但手动回滚等似乎太麻烦了。

    0 回复  |  直到 4 年前