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,各方法的事務(wù)屬性是required
客戶端調(diào)用tran以上代碼可以正確運(yùn)行嗎?
如果把tran1中的sf.getCurrentSession();改為sf.openSession()可以正確運(yùn)行嗎?
辨析:
1 上述代碼是不能正確運(yùn)行的,運(yùn)行tran2時(shí)會(huì)拋出異常,告訴你session is closed.
其實(shí)這是應(yīng)為getCurrentSession()會(huì)使用環(huán)境已有的Session,同時(shí)注意getCurrentSession()要在事務(wù)的環(huán)境中使用。
這是也許你一定會(huì)問(wèn),那么什么時(shí)候關(guān)閉Session呢?答案是事務(wù)完成的時(shí)候(提交或是回滾)。
2 如果上述代碼tran1中的sf.getCurrentSession();改為sf.openSession()代碼將可以正確運(yùn)行。這是因?yàn)閛penSession()每次都會(huì)返回一個(gè)新的Session。而在tran2種的sf.getCurrentSession()并不會(huì)使用tran1中的session,而是會(huì)使用當(dāng)前事務(wù)環(huán)境中的默認(rèn)的session.
也許你會(huì)問(wèn)如果tran2種的調(diào)用拋出RuntimeException,tran1所作的操作還可以回滾嗎?
答案是仍然可以回滾的.
蔡超
北京天融信 軟件架構(gòu)師
SCEA,SCBCD,MCSD
IBM Certified Specialist RUP v2003
IBM Certified Solution Designer OOA&D UMLv2