1

私 (JavaEE 開発に不慣れな人) にとっては、SessionContext インスタンスではなく、コンテナー管理の EntityManager が失敗したトランザクションのロールバックを担当すると思います。次のシナリオを想定してください...

@Stateless
public class MySessionBean implements MySessionBeanRemoteInterface {
    @PersistenceContext(unitName="MYPu")
    private EntityManager em;

    @Resource
    private SessionContext sctx;

    @Override
    public StackOverFlowUser createSOUser(String userName, int rep) {
         try {
             StackOverFlowUser su = new StackOverFlowUser();
             su.setUserName(stackOverflowName);
             su.setRep(rep);
             su.setIsBalusC(userName.equals("BalusC");
             su.setIsTheJonSkeet(userName.equals("jon skeet"));
             return em.merge(su);
         } catch (Exception e) {
             //sctx.setRollbackOnly();
             return null;
         }
    }

}

EntityManager がこれに責任を負わないのはなぜですか? なぜ SessionContext を使用するのでしょうか?

4

1 に答える 1

1

transaction-type="JTA"JPA ( ) ではなく、JTA ( ) を介してトランザクションを管理するようにコンテナーに指示したためですtransaction-type="RESOURCE_LOCAL"。JTA は、EJB コンテナによって管理されます。したがって、SessionContextここの役割。

しかし、私を悩ませているのは、例外を抑制して を返していることですnull。ビジネスサービスメソッドではそれをしない方がよいでしょう。を返すのではなく、例外を手放した方がよいでしょうnull。EJB コンテナは、例外的な場合に自動的にロールバックを実行します。try-catchEJB のandを取り除きreturn null、EJB のクライアントが例外自体を処理するようにします。

例えば

try {
    mySessionBean.createSOUser(userName, rep);
} catch (PersistenceException e) {
    showSomeGlobalErrorMessage(e.getMessage());
}

または、さらに良いことに、それをさらに下層のコンテナーに移動させます。たとえば、実際にサーブレット コンテナーの場合:

<error-page>
    <exception-type>javax.persistence.PersistenceException</exception-type>
    <location>/WEB-INF/errorpages/db-fail.xhtml</location>
</error-page>

あるいは、問題の MVC フレームワークには、そのためのカスタマイズ可能なグローバル例外ハンドラーさえあるかもしれません。少なくとも、JSF はこの機会を許します。そうすればtry-catch、サービス メソッドを呼び出すマネージド Bean メソッドですべての場所を繰り返す必要なく、faces メッセージをグローバルに設定できます。

以下も参照してください。

于 2015-06-03T17:22:38.937 に答える