我正在尝试理解事务管理,并尝试在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中启动旧的交易。
答案 0 :(得分:0)
容器管理的事务确实是开箱即用的EJB bean。但是,您的Dao
类不是托管bean - 它是您手动实例化的常规pojo - 因此它不参与您的其他ejb启动的任何事务。
请将Dao
移至单独的文件,使用@Stateless
对其进行注释,然后使用@EJB private Dao dao;
将其注入您的服务中
但是,Ejb容器中的交易还有很多。您可以通过@TransactionAttribute
注释控制方法级别的事务支持,该注释指定容器如何根据事务调用方法。这样你就可以控制,你的方法是否需要自己的事务,或者它是否应该参与调用者发起的事务(例如,从ejb bean调用时)。有关更多信息,请查看官方Java EE tutorial