4

Jersey で 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 アプリケーションに制御を戻してしまっているため、作業が完了した後にセッションを適切に解放できるかどうかを確認できません。

子もセッションにアクセスする必要があるため、すべての作業を 1 つのメソッドにカプセル化することはできません。

class Child {
  @Path("{subchild}") public Subchild getSubchild(...) {
    return new Subchild(session.get(...));
  }
}

セッションを構築するためにジャージー レベルからの情報が必要なため、アプリケーション全体をサーブレット フィルターでラップすることはできません。これで、MyResource で開くことができます。通常のサーブレット フィルターを使用して、常に閉じるようにしますが、ロールバックするタイミングとセッションをコミットするタイミングがわかりません。ExceptionMapper を使用してすべての例外を通知することもできますが、これは ExceptionMapper である必要があり、概念的な try/finally が異なるライフタイムを持つ 3 つのクラスに分散されているなど、非常に醜いように思えます。

Jersey でこの種のリソース管理を行う「正しい方法」はありますか? リソースとそのサブロカトがそれを使用した後、たとえば FileInputStream を適切に閉じるにはどうすればよいですか?

4

2 に答える 2

0

REST アプリケーションでは、呼び出しに何も渡す必要はありません。getChild で作業を行っている場合、そこにすべてのロジックがあるはずです。あなたが何をしているのかを推測すると、上記は次のようになります。

@Path("/{childId}")
class ChildResource {  

    @GET
    public Child getChild(@PathParam("childId") String childId) {    
        //Really, move this into a data access object
        Session session = getSession();
        try {  
            doWork();  
            session.commit();
        } finally {  
            session.rollback(); 
            // doesn't hurt after commit  
            session.release(); 
            // or whatever
        }
        return child;  
    }
}
于 2009-06-09T21:19:22.783 に答える
0

スプリングを使用します。そのようにリソースを手動で管理することは絶対にありません*。これは壊れたアプリケーションのレシピです。

*おそらくテストコードを除く

于 2011-08-09T01:32:06.827 に答える