论坛首页 Java企业应用论坛

『提问』关闭session的老问题

浏览 20781 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-11-09  
如果使用SLSB的话,你说得对,在部署文件里配置。那么代码的实现要好好琢磨一下。
0 请登录后投票
   发表时间:2004-11-09  
呵呵,原来是这样,使用SLSB其实我也就是想借用它的事务管理。
我目前的实现看起来没有太大问题,呵呵,碰到新问题再拿出来讨论,谢谢:)
0 请登录后投票
   发表时间:2004-11-09  
	private static final SessionFactory sessionFactory;
	public static final ThreadLocal sessionContext = new ThreadLocal();;

	private Session session = null;
	private int signal = 0;
	
        public static Session currentSession(); throws HibernateException 
	{
		HibernateUtil h = (HibernateUtil); sessionContext.get();;
		if ( h == null ); {
			h = new HibernateUtil();;
			h.session = sessionFactory.openSession();;
			h.signal = 0;
			sessionContext.set(h);;
		}
		h.signal++;
		return h.session;
	}

	public static void closeSession(); throws HibernateException
	{
		HibernateUtil h = (HibernateUtil); sessionContext.get();;
		if ( h!=null ); {
			h.signal--;
			if ( h.signal<=0 ); {
				if ( h.session!=null ); {
					h.session.close();;
				}
				sessionContext.set(null);;
			}
		}
	}


这样就不会把还有人使用的ThreadLocal session关掉了。
0 请登录后投票
   发表时间:2004-11-10  
葡萄藤 写道

...
这样就不会把还有人使用的ThreadLocal session关掉了。


这样倒没试过,但是感觉这样会不会比较容易出差错啊,万一哪个方法抛出异常了,就没法保证一定关闭session了呀,代码好像不够健壮的说
0 请登录后投票
   发表时间:2004-11-10  
引用
这样倒没试过,但是感觉这样会不会比较容易出差错啊,万一哪个方法抛出异常了,就没法保证一定关闭session了呀,代码好像不够健壮的说


只要你的事务操作都是规范的finally close就没事。
0 请登录后投票
   发表时间:2004-11-17  
leolin 写道
yangstarfly 写道
我的做法是在所有的方法里都不关闭,
最后在filter里统一关闭

你指的是servlet的filter 吗?我的DAO是提供给EJB使用的,我希望能在DAO这一层本身完全控制Hibernate,退一步在EJB中统一关闭也可以吧,在EJB中是否也可以实现对针对具体方法的Filter?

Filter模式能不能实现在一个DAO或者EJB中?对Filter不太了解的说


不知道你看过《Hibernate in action》没有。 其中第八章有讲到在servlet engine和EJB container里hibernate的用法。

servlet engine里没有问题,用request filter统一关闭, 但作者说道标准的ejb规范没有对interceptor模式的实现(servlet filter就是一个interceptor的实现), 原文如下:
  写道
class. A servlet filter is the servlet specification’s implementation of the
interceptor pattern. Unbelievably, the EJB specification provides no standard way to
implement interceptors for EJB method calls.

还说道像joss和weblogic有自己的实现, 不知道websphere有没有,去那里可以查到websphere对ejb的扩展资料,小弟也在琢磨。
《HIA》中提出了一种通用的解决之道--ejb的command模式, 但此模式需要在web层中引入hibernate的libraries,与其这样还不如依然用servlet filter来处理呢。不知道大家怎么看?

在SLSB的每一个方法里关闭session可不可以接受呢?
0 请登录后投票
   发表时间:2004-11-18  
《Hibernate in action》没有完整看,看E文还是辛苦啊,只挑着自己需要的看:)

在目前的实现来看,我还是完全在DAO里管理session的,之前出现的问题主要是我递归调用DAO方法本身出问题(也许DAO的设计就不好:(),最后干脆让这个方法每次new一个session,其他时候直接用HibernateUtil类还是很方便的。

没有太多的时间钻研,只能凑合着快快做完,哎
0 请登录后投票
   发表时间:2004-11-18  
我觉得session应该用完就关,因为session一直不关会导致transaction过多而使性能急剧下降。

而ThreadLocal这个东西是比较奇妙的,
不同的线程获取的session放在ThreadLocal里面的时候是不会覆盖的,同样获取的时候也是一样,也就是说ThreadLocal是通过ProcessID/ThreadID来存放session值的。

这也就是currentSession函数作为singleton模式却没有synchronized的原因!(很多人没有注意到这个细节)
  public static Session currentSession(); throws HibernateException
  {
    Session s = ( Session ); session.get();;
    // Open a new Session, if this Thread has none yet
    if ( s == null ); {
      s = sessionFactory.openSession();;
      session.set( s );;
    }
    return s;
  }




对于以servlet为主的系统,如果servlet没有实现SingleThreadModel接口,那么每次客户访问都会使服务器产生新的线程,所以不通过自己编程手段是无法通过ThreadLocal获取到原来那个session,这时还不如重新产生一个呢。


对于application为主的系统,线程就那么几个,怎么用都成,无所谓ThreadLocal来管理session了。
0 请登录后投票
   发表时间:2004-11-18  
leolin 写道
yangstarfly 写道
我的做法是在所有的方法里都不关闭,
最后在filter里统一关闭

你指的是servlet的filter 吗?我的DAO是提供给EJB使用的,我希望能在DAO这一层本身完全控制Hibernate,退一步在EJB中统一关闭也可以吧,在EJB中是否也可以实现对针对具体方法的Filter?

Filter模式能不能实现在一个DAO或者EJB中?对Filter不太了解的说



上面有人说过统一管理session然后统一关闭,其实也是可以的,这个时候你就不需要用ThreadLocal来管理了。只需要自己实现一个Session的单例模式,每次访问时先要这个session然后没有就产生它!

但这样同样在多线程模式下会有问题,因为不同的用户要求要有不同的session,所以在session被别的用户用的时候,只能等待或者可能hibernate报错。

因此,顶多是实现hibernate的session和web的session进行绑定,这样确实也是一种不错的方法,毕竟一个用户不大可能同时进行多次数据库操作。




至于上面的兄台说直接在DAO里面控制Hibernate,那你就错了!!
要知道,DAO层是完全抽象的,不应该和具体数据库打交道,比较好的实现是

[package]DAO ---纯业务接口
[package]IbatisDAOImpl   --- 基于IBATIS实现的DAO implementation
[package]hibernateDAOImpl  --- 基于hibernate实现的DAO implementation
[api layer--class]DAOProvider   -- 统一为presentation layer提供DAO对象


而在DAOProvider类中,就很灵活多变了,可以选择使用XML配置文件绑定实现类,class.ForName找到类并加载。或者使用写死代码的方式等等,总之,以后要是更换了DAO的实现方式,只需要实现impl层,然后更改DAOProvider类,如果写了配置文件,甚至只需要修改配置文件就立即更换了db层,而p层不需要任何修改。
0 请登录后投票
   发表时间:2004-11-18  
http://www.hibernate.org.cn/92.html

所有的lazy=true,而并不影响你灵活的进行对象图的访问,
在项目中的实践非常好,极大地提高了数据库访问的效率,毕竟不停的开关session,效率的损伤太大了
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics