主要是机制问题,在一个系统中Session是否是单例?如何进行并发处理?

解决方案 »

  1.   


    这个例子似乎有点问题.我试过访问经过一段时间后,如果没有动作会自动断开连接数据库,
    而且网站也访问不了.
    这种情况不用hibernate的项目遇到,一个是delphi的项目,一个是J2EE项目.后者是系统安全策略导致的.
      

  2.   

    是不是你在获取session并在使用完之后调用了session.close()方法,导致ThreadLocal里面存放的是一个关闭了的session。
      

  3.   

    使用的是单例模式,但调用的 session 是多例的.并且是一个session 的多个实例
      

  4.   

    那么是不是说,使用session后不用关闭?
      

  5.   

    当然是多例的,官方建议用ThreadLocal,但是这好象是有限制的。我记得在网上一篇文章上看过,用ThreadLocal不一定是最好的,有的时候会出现问题。你用google搜一下,兴许能找到。
      

  6.   

    我用ThreadLocal就遇到一些问题,如果每次使用完Session之后,调用closeSession()方法,关闭了Session,后我该如何使用延迟加载策略呢
      

  7.   

    HibernateUtil代码个人觉得本身似乎有些问题,既然每次取得都是绑定到本地线程的Session,为什么还需要每次调用完都关闭掉自己的Session, 何不在应用关闭的时候统一关闭或者可能也会自动的关闭代码中
    public static Session currentSession() throws HibernateException {
    Session s = (Session) session.get();既然每次取currentSession()都会取绑定在本地线程上的session,Session s = (Session) session.get();
    session.set(null);如果每次都要求使用完关闭
    也就会使以后再次使用session,通过
    Session s = (Session) session.get();
    取出来的s总是为null
      

  8.   

    TO rainshow:
      是的,目前我是调用完Session之后就关闭它,所以才出现了后来取得的Session都是关闭的.TO CAYU:
      <--
        使用的是单例模式,但调用的 session 是多例的.并且是一个session 的多个实例
      -->  呵呵,我不是很明白其中的含义,能解释清楚一点吗?大家多发表一下高见啊!
      

  9.   

    HibernateUtil类成员ThreadLocal xxx是一个典型的单态设计模式,这一点是肯定的。被存/取的Session实例既然和ThreadLocal的单例关联(the value associated with the ThreadLocal)我认为也是单例
      

  10.   

    当然是单线程的了,在查询时不需要关闭SESSION, 在执行 提交操作后才需要关闭SESSION. 每一个SESSION 被放在ThreadLocal 的对象里面,它会跟据请求的对象到判断是否新创建一个SESSION 连接.用的时候一定要小心了,不然后出现SESSION 没有被关闭的警告的.嘿嘿
      

  11.   

    xdop(鸿飞处):我晕倒,你研究一下ThreadLocal再说Session是不是单例的嘛,相对某线程来说,可能是单例,单整体来说,无数例了。
      

  12.   

    用户的每次请求都是一个新的线程,会被分配一个新的session,而不是ThreadLocal中原有的那个。使用ThreadLocal是为了避免并发时不同用户调用同一个session。应该在每次请求结束时关闭session
      

  13.   

    怎么用单例,用单例的话,session就只有一个,大家都用,如果有一处session.close之后,其他人都不能用了
      

  14.   

    我遇到过跟你类似的问题,是因为我错用了session.close()而非HibernateUtil.closeSession()来关闭session;
    因为并没有调用HibernateUtil.closeSession(),所以也就没有调用ThreadLocal.set(null)去清除ThreadLocal内部hash中对应的session,因此当你下次调用HibernateUtil.currentSession()的时候返回的还是那条被你close掉的session。所以就会报出Session已关闭的错误!
    不知道你是不是也分我犯了一样的错误 ^ ^
      

  15.   

    我犯的错与楼上的相同!Session sn1 = HibernateUtil.currentSession();
    Session sn2 = HibernateUtil.currentSession();
    System.out.println(sn1.hashCode()+", "+sn2.hashCode());大家看一下结果就明白是单例还是多例!
      

  16.   

    调用完毕好用HibernateUtil.closeSession(),就可以清空ThreadLocal里的session的!
      

  17.   

    你绑定在ThreadLocal 后get 的是这个session 的复制(相当一个虚拟对象),内部变量是相对独立的.
    session 就是一个,没有多的,你关闭了就都关闭了.所以在使用的时候不要 closeSession() 就当它没有好了.只有在发生异常的时后建议关闭.延迟加载策略 在这种模式下就不能很好的使用了.
    如果你真想使用延迟加载策略那得换个方法了. 比如使用页面过滤,在页面打开的时候打开session,
    页面关闭的时候在关闭session.网上也有这个代码的.但对本人研究的结果来说速度最块的,还是ThreadLocal.其他的方法我测试了效果都不是很好.期待能有更好的方法.
      

  18.   

    上边错了一点 延迟加载策略 只要不closeSession() 就可以使用了
      

  19.   

    ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
      

  20.   

    在下面的方法中试着加入如下一句试试: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();//add here!
    s.connection().setAutoCommit(true);session.set(s);
    }
    return s;
    }在关闭时候再加入一句s.flush();应该就行了
      

  21.   

    回复owenchwz() ( ) 信誉:100  2005-9-5 8:48:12  得分: 0  
        
    我怎么结这个贴呀? ---------------------
    最简单的办法是, 点管理->填写密码->找到我的名字(CAYU(中原)) ->然后填上100->在点给分
    就ok了
    :)