1

对我(JavaEE 开发新手)来说,我认为容器管理的 EntityManager 将负责回滚失败的事务,而不是 SessionContext 实例。假设以下场景...

@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

因为您告诉容器通过 JTA ( transaction-type="JTA") 而不是 JPA ( transaction-type="RESOURCE_LOCAL") 来管理事务。JTA 反过来由 EJB 容器管理。因此SessionContext这里的作用。

但是困扰我的是,您正在抑制异常并返回null。您最好不要在业务服务方法中这样做。你最好让异常消失而不是返回null。EJB 容器将在任何异常情况下自动执行回滚。摆脱 EJB 中的try-catchandreturn null并让 EJB 的客户端自己处理异常。

例如

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

或者,更好的是,让它进一步进入底层容器。例如,如果它实际上是一个 servlet 容器:

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

或者,有问题的 MVC 框架甚至有一个可定制的全局异常处理程序。至少,JSF 允许这个机会,然后您可以全局设置一个 faces 消息,而无需重复try-catch调用服务方法的托管 bean 方法中的所有位置。

也可以看看:

于 2015-06-03T17:22:38.937 回答