J2EE之巅

 

EJB中使用Hibernate的几个问题辨析

public class HibernateTestBean implements SessionBean {
    SessionContext sessionContext;
    SessionFactory sf;
    public void setSessionContext(SessionContext sessionContext) {
        this.sessionContext = sessionContext;
        try {
            InitialContext ctx = new InitialContext();
            sf=(SessionFactory) ctx.lookup("java:/hibernate/SessionFactory");
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
    }
    public void tran(){
        tran1();
        tran2();
       
    }
    public void tran1() {
        Session session=sf.getCurrentSession();
        Message msg=new Message();
        msg.setCreateTime(new Date());
        msg.setDetail("trans1");
        session.save(msg);
        System.out.println("Session:"+session.hashCode());
        session.flush();
        session.close();
    }
    public void tran2() {
      Session session=sf.getCurrentSession();
      Message msg=new Message();
      msg.setCreateTime(new Date());
      msg.setDetail("trans2");
      session.save(msg);
       System.out.println("Session:"+session.hashCode());
    //  throw new RuntimeException("wrong");
  }
……
}
注:EJB采用CMT,各方法的事务属性是required
客户端调用tran以上代码可以正确运行吗?
如果把tran1中的sf.getCurrentSession();改为sf.openSession()可以正确运行吗?
辨析:
1 上述代码是不能正确运行的,运行tran2时会抛出异常,告诉你session is closed.
其实这是应为getCurrentSession()会使用环境已有的Session,同时注意getCurrentSession()要在事务的环境中使用。
这是也许你一定会问,那么什么时候关闭Session呢?答案是事务完成的时候(提交或是回滚)。

2 如果上述代码tran1中的sf.getCurrentSession();改为sf.openSession()代码将可以正确运行。这是因为openSession()每次都会返回一个新的Session。而在tran2种的sf.getCurrentSession()并不会使用tran1中的session,而是会使用当前事务环境中的默认的session.
也许你会问如果tran2种的调用抛出RuntimeException,tran1所作的操作还可以回滚吗?
答案是仍然可以回滚的.


蔡超
北京天融信 软件架构师
SCEA,SCBCD,MCSD
IBM Certified Specialist RUP v2003
IBM Certified Solution Designer OOA&D UMLv2

posted on 2007-08-19 19:44 超越巅峰 阅读(934) 评论(0)  编辑  收藏 所属分类: Java EE


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(12)

随笔分类(54)

随笔档案(59)

文章分类(2)

文章档案(1)

相册

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜