锁定老帖子 主题:Hibernate文档上的这段话如何解释?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2003-11-24
他就是说用ThreadLocal可以解决lazy="false"的bug. 谁有个用ThreadLocal的具体的例子来说明上面这段话? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2003-11-24
随便写了一下,没有严格的Test,参考一下吧
/* * Created on 2003-11-16 * */ import net.sf.hibernate.HibernateException; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.Transaction; import net.sf.hibernate.cfg.Configuration; import net.sf.hibernate.tool.hbm2ddl.SchemaExport; /** * * 获取Session连接工厂类 * * @author Robbin Fan * */ public class ReportSession { private static final ThreadLocal sessionThread = new ThreadLocal();; private static final ThreadLocal transactionThread = new ThreadLocal();; /** * 获取当前线程使用的Session * * @return Session * @throws HibernateException */ public static Session currentSession(); throws HibernateException { Session s = (Session); sessionThread.get();; if (s == null); { SessionFactory sf = new Configuration();.configure();.buildSessionFactory();; s = sf.openSession();; sessionThread.set(s);; } return s; } /** * 启动或者加入当前Session的Transaction * * @return Transaction * @throws HibernateException */ public static Transaction currentTransaction(); throws HibernateException { Transaction tx = (Transaction); transactionThread.get();; if (tx == null); { tx = currentSession();.beginTransaction();; transactionThread.set(tx);; } return tx; } /** * 提交当前Session的Transaction * * @throws HibernateException */ public static void commitTransaction(); throws HibernateException { Transaction tx = (Transaction); transactionThread.get();; transactionThread.set(null);; if (tx != null); tx.commit();; } /** * 关闭当前线程使用的Session * * @throws HibernateException */ public static void closeSession(); throws HibernateException { Session s = (Session); sessionThread.get();; sessionThread.set(null);; if (s != null); s.close();; } /** * 根据映射文件和持久对象生成数据库DDL,生成文件为create_table.sql * * @param args 参数 */ public static void main(String[] args); { try { Configuration cfg = new Configuration();.configure();; SchemaExport se = new SchemaExport(cfg);; se.setOutputFile("create_table.sql");; se.create(true,true);; } catch (HibernateException e); { e.printStackTrace();; } } } |
|
返回顶楼 | |
发表时间:2003-11-24
在程序里面使用Hibernate这样来获得Session和Transaction,不用提交Transaction和关闭Session,如果是查询,那么不需要启动Transaction。
try { Session s = ReportSession.currentSession();; ReportSession.currentTransaction();; ... s.save(...);; ... s.flush();; } catch (HibernateException e); { e.printStackTrace();; } 在ServletFilter的doFilter方法里面写如下代码出来Transaction和关闭Session: ReportSession.commitTransaction();; ReportSession.closeSession();; |
|
返回顶楼 | |
发表时间:2003-11-24
robbin 写道 /** * 获取当前线程使用的Session * * @return Session * @throws HibernateException */ public static Session currentSession(); throws HibernateException { Session s = (Session); sessionThread.get();; if (s == null); { SessionFactory sf = new Configuration();.configure();.buildSessionFactory();; s = sf.openSession();; sessionThread.set(s);; } return s; } |
|
返回顶楼 | |
发表时间:2003-11-24
多谢,我好好理解一下
|
|
返回顶楼 | |
发表时间:2003-11-24
tomcat 写道 robbin 写道 /** * 获取当前线程使用的Session * * @return Session * @throws HibernateException */ public static Session currentSession(); throws HibernateException { Session s = (Session); sessionThread.get();; if (s == null); { SessionFactory sf = new Configuration();.configure();.buildSessionFactory();; s = sf.openSession();; sessionThread.set(s);; } return s; } 怀疑这段代码有问题:会不会生成多个 sf 呢? 明天测试一下。 有可能会,如果第一次请求的时候,就有很多线程并发,就会产生好几个sf,不过即使产生好几个sf也无关紧要,对程序也没有什么影响。实际上只要初始sf生成了,以后多个线程并发就不会产生sf了,只有一个sf。所以这种情况只会出现在应用软件第一次被访问的时候,并且是第一次被访问就有多线程并发才会出现,因此出现的几率很小,并且就算出现了,对整个软件来说,也没有什么影响。因此这个问题可以不用去管它的。 如果你严格限制只产生一sf,那么可以给这个方法进行synchronized,那么就会保证永远产生一个sf,但是代价很高,多线程实际上不能够真正的并发执行了,会影响多线程并发的时候Session获得的性能。 |
|
返回顶楼 | |
发表时间:2003-11-24
多谢,我好好理解一下
|
|
返回顶楼 | |
发表时间:2003-11-27
robbin 写道 tomcat 写道 robbin 写道 /** * 获取当前线程使用的Session * * @return Session * @throws HibernateException */ public static Session currentSession(); throws HibernateException { Session s = (Session); sessionThread.get();; if (s == null); { SessionFactory sf = new Configuration();.configure();.buildSessionFactory();; s = sf.openSession();; sessionThread.set(s);; } return s; } 怀疑这段代码有问题:会不会生成多个 sf 呢? 明天测试一下。 有可能会,如果第一次请求的时候,就有很多线程并发,就会产生好几个sf,不过即使产生好几个sf也无关紧要,对程序也没有什么影响。实际上只要初始sf生成了,以后多个线程并发就不会产生sf了,只有一个sf。所以这种情况只会出现在应用软件第一次被访问的时候,并且是第一次被访问就有多线程并发才会出现,因此出现的几率很小,并且就算出现了,对整个软件来说,也没有什么影响。因此这个问题可以不用去管它的。 如果你严格限制只产生一sf,那么可以给这个方法进行synchronized,那么就会保证永远产生一个sf,但是代价很高,多线程实际上不能够真正的并发执行了,会影响多线程并发的时候Session获得的性能。 robbin,你在上面说“有很多线程并发,就会产生好几个sf,不过即使产生好几个sf也无关紧要,对程序也没有什么影响” 那这些产生出来的多余的SF,在什么时候被关闭和释放呢? |
|
返回顶楼 | |
发表时间:2003-11-27
是不是可以考虑用threadlocal做一个stack放sf, 或者Double check处理一下.
|
|
返回顶楼 | |
发表时间:2003-11-27
sf不打开数据库,不占用数据库资源,不需要显式释放。
|
|
返回顶楼 | |