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所作的操作还可以回滚吗?
答案是仍然可以回滚的.