--------------------------------------------------------------------------------
 代码
package com.censoft.portlets.db.base;   
import com.censoft.portlets.db.DbTools;   
import net.sf.hibernate.*;   
import net.sf.hibernate.cfg.*;   
public class HibernateSession {   
  
  public static final ThreadLocal sessionContext = new ThreadLocal();   
  private Session session;   
  private int level;   
  
  public static Session currentSession(String cfgFilePath) throws Exception {   
    HibernateSession hSession = (HibernateSession)sessionContext.get();   
    if (hSession == null)   
    {   
        hSession = new HibernateSession();   
        SessionFactory factory = DbTools.getSessionFactory(cfgFilePath);   
        hSession.session = factory.openSession();   
        hSession.level = 0;   
        sessionContext.set( hSession );   
    }   
    hSession.level++;   
    return hSession.session;   
  }   
  
  public static void closeSession() throws Exception {   
    HibernateSession hSession = (HibernateSession)sessionContext.get();   
    if (hSession == null)   
    {   
        return;   
    }   
    hSession.level--;   
    if (hSession.level <= 0)   
    {   
        if (hSession.session != null && hSession.session.isOpen())   
        {   
            hSession.session.close();   
        }   
        sessionContext.set( null );   
    }   
  }   
  
}    
 
在同一个线程里只使用一个session对象

解决方案 »

  1.   

    bushuang的代码是用了ThreadLocal创建session,不知道所说的“在同一个线程里只使用一个session对象”是如何使用的?
    比如我封装的存储和删除的函数分别如下:
    <!--存储函数-->
    public static boolean merge(Object o) throws HibernateException { /*
     * 創建session,存儲對象,最後關閉session
     */
    Session s = HibernateSessionFactory.getSession();
    Transaction tx = s.beginTransaction();
    boolean result = false;
    try {
    s.merge(o);
    tx.commit();
    result = true;
    } catch (HibernateException he) {
    tx.rollback();
    throw he;
    } finally {
    if (s != null) {
    s.close();
    }
    }
    return result;
    }
    <!--删除函数-->
    public static boolean deleteObject(String hql) {
    try { /*
     * 創建session,存儲對象,最後關閉session
     */
    Session s = HibernateSessionFactory.getSession();
    Transaction tx = s.beginTransaction();
    Query query = s.createQuery(hql);
    query.executeUpdate();
    tx.commit();
    s.close();
    return true;
    } catch (Exception e) {
    e.printStackTrace();
    return false;
    }
    }
    调用的时候先调用存储再调用删除,如果删除过程异常则想要把存储过程回滚,但我已经commit调了。
    我的问题是应该如何改造这些函数?
      

  2.   

    hibernate在3.1版本以后 session的封装已经是单态模式了 所以不用担心 session 有多个session(3.0版没注意看过)
    如果你 想在调用 save 在delete 那么你就要把 save 里的事务去掉 这样就可以了
    也就是所按调用的顺序去掉事务 保存最后一个事务
    这样才能保证 save 和delete 在同一个事务中
      

  3.   

    小弟就 Hibernate 的JTA事务应用花了三天的时间才算搞好,真是有点汗颜。在网上搜出来的例子,都不能用,可能小弟的Java基础太弱了。不知道大家是不是都是用JTA的事务。网上的例子可都是用 Session 的事务。写出来,以防止自己以后忘记了。呵呵。由于我不断尝试,所以,现在写下的是最后的结果,如果有谁知道其中有哪些步骤可以省略,请告诉我。这次就是使用:Tomcat + Hibernate + JOTM 1. 在Tomcat中配置 JOTM (http://www.objectweb.org/jotm/)
       先到上述网站上下载JOTM。然后将
           jotm.jar 、jotm_jrmp_stubs.jar 、jonas_timer.jar 、carol.jar 、jta-spec1_0_1.jar 
              jts1_0.jar 、objectweb-datasource.jar 、xapool.jar 
        这些Jar文件复制到:$TOMCAT_HOME/common/lib/ 目录中。
       将JDBC driver 复制到: $TOMCAT_HOME/common/lib/ 目录中。   将文件:carol.properties 复制到:$TOMCAT_HOME/common/classes/ 目录中。   下面,修改 Tomcat 的 Server.xml 配置文件。
       [code] 
         <Resource name="jdbc/dataSrc" auth="Container" type="javax.sql.DataSource"/>
         <parameter>
     <name>factory</name>
     <value>org.objectweb.jndi.DataSourceFactory</value>
                    ..........
         </parameter>
         <Resource name="UserTransaction" auth="Container" 
                           type="javax.transaction.UserTransaction"/>
         <ResourceParams name="UserTransaction">
                 <parameter>
                           <name>factory</name>
                           <value>org.objectweb.jotm.UserTransactionFactory</value>
                 </parameter>
                 <parameter>
                           <name>jotm.timeout</name>
                           <value>60</value>
                 </parameter>
         </ResourceParams>
         [/code]
       注意上面的数据库连接池的配置,要用 JOTM 中的 XAPool 。
       基本上,我们就配置好了 Tomcat 中的 JOTM。2。Hibernate中的事务配置。(我想这步可以省略,但还没测试。请有心人测试一下。)
       在 hibernate.cfg.xml 中   <property name="transaction.factory_class"> 
             net.sf.hibernate.transaction.JTATransactionFactory
        </property>
        <property name="transaction.manager_lookup_class">
             net.sf.hibernate.transaction.JOTMTransactionManagerLookup
        </property>
        <property name="jta.UserTransaction">
             java:comp/UserTransaction
        </property>
     好了,现在可以使用网上最常见的代码:
     
    1  javax.transaction.UserTransaction tx = 
    2                               new InitialContext().lookup("java:comp/UserTransaction"); 
    3 tx.begin();
    4
    5  Session s1 = sf.openSession(); 
    6  ... 
    7  s1.flush(); 
    8  s1.close(); 
    9   
    10  ... 
    11 
    12 Session s2 = sf.openSession(); 
    13 ... 
    14 s2.flush(); 
    15 s2.close(); 
    16  
    17 tx.commit();
     
      

  4.   

    UserTransaction utx = ( UserTransaction )new InitialContext().lookup( "java:comp/UserTransaction" );
    得到的utx为null.