【问题标题】:Transaction management in EJB 3.0 and hibernateEJB 3.0 和休眠中的事务管理
【发布时间】:2017-06-04 12:01:23
【问题描述】:

我正在尝试了解事务管理,并尝试在我已经存在的应用程序中使用它的强大功能,这些应用程序是用 Struts 2、EJB 3 和 hibernate 5.2 开发的。 现在我的业务层中有 ejb,如下所示

   @Stateless
    @TransactionManagement(TransactionManagementType.CONTAINER)
    public class MyEJb implements ejbxyz {

    @Override
    public void method(){
          Dao dao=new Dao() //Dao class is simple java class
          dao.fooMethod();  //this method updates some record
          dao.barMethod();  // this method updates some other record
        }
    } 

    public class Dao{
         fooMethid(){
         Session session=sessFactory.openSession();
          session.beginTransaction();
         session.update(x);
              }
         barMethod(){
              try{
                   Session session=sessFactory.getCurrentSession();
                    session.getNamedQuery("xyz").executeUpdate();

                }catch(HibernateException ex){
                    session.getTransaction.rollback();
                } 
             }
           }

我知道事务管理应该在服务层完成(在我的例子中是 ejb)。但是我怎样才能在那里实现这一点。 ?

现在的依赖是如果 barMethod() 无法更新记录,那么我需要回滚在 fooMethod 中所做的更改。所以基本上我需要在一个事务中完成这两种方法。 当我执行应用程序时,它会引发以下异常

Exception while barMethod getNamedQuery is not valid without active transaction

这是因为我没有在 barMethod 中开始任何事务。但是后来我真的不想开始一个新事务,而是想继续在 fooMethod 中启动的旧事务。

【问题讨论】:

  • 如您所说:事务管理应该在服务层完成。确实如此,因为您使用的是无状态 EJB,它会为您启动和提交事务。所以不要在 DAO 方法中处理事务。事务由 EJB 容器自动为您处理。而且,不要使用专有的 Hibernate API。使用 JPA。
  • @JBNizet 您能否详细说明“不要使用专有的 Hibernate API。使用 JPA”。 hibernate 不是 JPA 实现吗?
  • Java EE 有一个名为 JPA 的标准规范。它定义了标准接口(EntityManager...)、方法、注释。 Hibernate 是 JPA 的一个实现。您应该使用标准 API 而不是专有的 Hibernate Session API。

标签: java hibernate ejb-3.0


【解决方案1】:

容器管理的事务确实为 EJB bean 提供了开箱即用的支持。但是,您的 Dao 类不是托管 bean - 它是您手动实例化的常规 pojo - 因此它不参与您的其他 ejb 启动的任何事务。 因此,将您的 Dao 移动到单独的文件中,使用 @Stateless 对其进行注释,然后使用 @EJB private Dao dao; 将其注入您的服务中
不过,Ejb 容器中的事务还有更多。您可以通过@TransactionAttribute 注释在方法级别控制事务支持,该注释指定容器应如何调用您的关于事务的方法。这样你就可以控制你的方法是否需要它自己的事务,或者它是否应该参与由调用者发起的事务(例如,当从 ejb bean 调用时)。更多信息请查看官方Java EE tutorial

【讨论】:

  • 好的。但是你不认为将dao标记为ejb会增加容器的开销吗?我只是好奇。
  • 不是真的,现在你的 Dao 被固定到你的 MyEjb 池中,所以对于 MyEjb 的每个实例都有一个 Dao 实例。如果你把 Dao 变成专用的 bean,它就会有自己的池,并且会被注入到 MyEjb 中。单个托管 bean 的开销可以忽略不计,您的服务器可以愉快地为数百个 bean 提供服务。专注于您的业务逻辑并让服务器完成其工作,您可能根本不需要任何性能调整;)
猜你喜欢
  • 1970-01-01
  • 2012-08-08
  • 2011-11-16
  • 2017-05-09
  • 1970-01-01
  • 2011-06-23
  • 2016-08-20
  • 1970-01-01
  • 2019-03-16
相关资源
最近更新 更多