我正在尝试在泽西岛编程 RESTful Web 应用程序时管理竞争资源(如:数据库会话)。通常我会写这样的代码:
Session session = getSession();
try {
doWork();
session.commit();
} finally {
session.rollback(); // doesn't hurt after commit
session.release(); // or whatever
}
现在有了泽西岛,我有这样的资源:
@Path("/")
class MyResource {
@Path("{child}") public Child getChild(...) {
// how do I manage my session here ???
return child;
}
}
问题是我需要在 getChild() 中获取会话,但我无法确保在工作完成后正确释放它,因为我已经将控制权交还给 Web 应用程序。
Child 也需要访问会话,因此我无法将所有工作封装在一种方法中:
class Child {
@Path("{subchild}") public Subchild getSubchild(...) {
return new Subchild(session.get(...));
}
}
我无法将整个应用程序包装在 servlet 过滤器中,因为我需要来自 Jersey 级别的信息来构建我的会话。现在我可以在 MyResource 中打开它,使用常规的 servlet 过滤器来确保我总是关闭它,但是我不知道何时回滚以及何时提交会话。我可以使用 ExceptionMapper 来通知所有异常,但这需要是一个 ExceptionMapper,这看起来非常丑陋,概念上的 try/finally 分布在三个具有不同生命周期的类上,依此类推。
在泽西岛进行这种资源管理是否有“正确的方法”?我将如何确保在资源及其子位置使用它之后正确关闭例如 FileInputStream?