【问题标题】:how to rollback on caught exception in Play framework?如何回滚 Play 框架中捕获的异常?
【发布时间】:2018-04-29 09:44:37
【问题描述】:

我最近遇到了 play framework 2 @Transactional 的问题。根据我的测试,在发生异常的情况下,只有在未检查异常(没有 catch 块)时,事务方法才会回滚。 这是我的控制器:

@Transactional
public Result myController(){
    ObjectNode result = Json.newObject();
    try{
        JsonNode json = request().body().asJson();

        someFunction(json);      
        //doing some stuff using the json object inside someFunction
        //which I may intentionally throw an exception
        //based on some logic from within
        //(using "throw new RuntimeException()")

        result.put("success", true);
        return ok(Json.toJson(result));
    }catch(Exception e){
        result.put("success", false);
        result.put("msg", e.getMessage());
        return internalServerError(Json.toJson(result));
    }

}

我希望我的控制器始终返回 JSON 作为响应。但这是以我在代码中抛出异常时没有数据库回滚为代价的。我知道在春天你可以将它添加到@Transactional 注释中,但我使用的是 play.db.jpa.Transactional。有什么方法可以在不使用弹簧的情况下在我的 catch 块中回滚?

【问题讨论】:

    标签: java hibernate jpa playframework transactions


    【解决方案1】:

    @Transactional 注释基本上将您的操作代码封装在对DefaultJpaApi.withTransaction 的调用中。如果您查看the source,您可以看到此方法如何处理事务。

    由于您想捕获异常,但仍想使用withTransaction 行为,您可以尝试删除@Transactional 注释并在操作中自己调用withTransaction

    例如

    class MyController {
      private final JPAApi jpa;
      @Inject
      public MyController(JPAApi jpa) {
        this.jpa = jpa;
      }
    
      public myAction() {
        ObjectNode result = Json.newObject();
        try {
          JsonNode json = request().body().asJson();
    
          // Calls someFunction inside a transaction.
          // If there's an exception, rolls back transaction
          // and rethrows.
          jpa.withTransaction(() -> someFunction(json));
    
          // Transaction has been committed.
          result.put("success", true);
          return ok(Json.toJson(result));
        } catch(Exception e) {
          // Transaction has been rolled back.
          result.put("success", false);
          result.put("msg", e.getMessage());
          return internalServerError(Json.toJson(result));
        }
      }
    }
    

    【讨论】:

    • 我用另一种方法重写了答案。
    • 我这样做并得到编译错误“未处理的异常:java.lang.throwable”。我应该如何解决这个问题?我应该在 catch 块中用 Throwable 替换 Exception 吗?
    • 是的,这会起作用,但是抛出 Throwable 的原因是什么?
    • withTransaction 确实
    • withTransaction 只是捕获并重新抛出异常,因此它可能不是错误的根本原因。如果您帮助解决这个问题,您需要发布更多的堆栈跟踪。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    相关资源
    最近更新 更多