Java 如何在Play框架中回滚捕获的异常?
我最近遇到了play framework 2@Transactional的问题。根据我的测试,在出现异常的情况下,事务方法只有在未选中异常(无catch块)时才会回滚。 这是我的控制器:Java 如何在Play框架中回滚捕获的异常?,java,hibernate,jpa,playframework,transactions,Java,Hibernate,Jpa,Playframework,Transactions,我最近遇到了play framework 2@Transactional的问题。根据我的测试,在出现异常的情况下,事务方法只有在未选中异常(无catch块)时才会回滚。 这是我的控制器: @Transactional public Result myController(){ ObjectNode result = Json.newObject(); try{ JsonNode json = request().body().asJson();
@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作为响应。但这样做的代价是,当我在代码中抛出异常时,数据库不会回滚。我知道在spring中,您可以将其添加到@Transactional注释中,但我使用的是play.db.jpa.Transactional。有没有什么方法可以不用spring在catch块中进行回滚 注释
@Transactional
基本上将操作的代码包装在调用DefaultJpaApi.withTransaction
中。如果查看,您可以看到此方法如何处理事务
由于您希望捕获异常,但仍然希望使用with transaction
行为,因此可以尝试删除@Transactional
注释,并在操作中自己调用with transaction
例如
我用另一种方法重写了答案,我这样做了,得到了编译错误“UnhandledException:java.lang.throwable”。我该如何解决这个问题?我应该在catch块中将异常替换为Throwable吗?是的,这会起作用,但是抛出
Throwable
?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));
}
}
}