在Spring Boot中不使用异常作为流控制时的服务方法事务性

时间:2018-07-19 21:06:43

标签: spring spring-boot spring-data-jpa spring-data

我在@Service类中定义了@Transactional的以下方法:

  @Override
  public Result add(@NonNull final UserSaveRequest request) {
    final Result<Email> emailResult = Email.create(request.getEmail());
    final Result<UserFirstName> userFirstNameResult = UserFirstName.create(request.getFirstName());
    final Result<UserLastName> userLastNameResult = UserLastName.create(request.getLastName());

    final Result combinedResult = Result.combine(emailResult, userFirstNameResult, userLastNameResult);
    if (combinedResult.isFailure()) {
      return Result.fail(combinedResult.getErrorMessage());
    }

    final Result<User> userResult = User.create(emailResult.getValue(), userFirstNameResult.getValue(), userLastNameResult.getValue());
    if (userResult.isFailure()) {
      return Result.fail(userResult.getErrorMessage());
    }

    this.userRepository.save(userResult.getValue());

    return Result.ok();
  }

现在您可以看到,我使用了一个Result类,该类可以包含返回值或错误消息,因为我认为使用异常进行流控制不是很干净。

我现在遇到的问题是; complete方法绑定在一个事务中,如果一个数据库调用失败,则将回滚整个事务。但是,在我的模型中,在this.userRepository.save(userResult.getValue());调用之后,如果发生某些事情会迫使我返回失败的结果,我将无法撤消该save(userResult.getVlaue());调用,因为我没有对流使用异常控制。

这是一个有一个优雅解决方案的问题,还是我需要在使用异常作为流控制与在这种情况下从心理上跟踪语句的顺序之间进行权衡的地方?

1 个答案:

答案 0 :(得分:1)

是的,您可以手动触发回滚。试试这个:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

更多信息:https://docs.spring.io/spring/docs/5.0.7.RELEASE/spring-framework-reference/data-access.html#transaction-declarative-rolling-back