kapok

          垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            455 隨筆 :: 0 文章 :: 76 評論 :: 0 Trackbacks
          http://forum.javaeye.com/viewtopic.php?t=4588&highlight=threadlocal




          wes109 寫道:
          ThreadLocal可以解決一定的事務問題
          但在Web應用中,我發現在filter里面close連接無疑是最合適的

          如果在其他地方close 連接,后面的調用得到的connection就是isColsed,無法再使用,如果再open一次,就不是以前的連接了,就無法保證事務了

          并且用ThreadLocal實現的也只是粗粒度的事務,尤其是在B/S應用中

          ThreadLocal,雞肋? Question


          你為什么要在其他地方close呢?

          事務的scope是在Session的scope里面的,你都已經close了Session了,當然不會在一個事務里面了。

          你怎么知道是粗粒度,那是你不會用,你就不會把Transaction也放到ThreadLocal里面,實現細粒度的事務控制嗎?貼段代碼給你參考:

          java代碼: 

          /*
          * Created on 2003-11-16
          *
          */

          package com.javaeye.crm;

          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 HibernateSession {       
                 
                  private static final ThreadLocal sessionThread = new ThreadLocal();
                 
                  private static final ThreadLocal transactionThread = new ThreadLocal();
                 
                  private static SessionFactory sf = null;
                 
                  /**
                  * 獲取當前線程使用的Session
                  *
                  * @return Session
                  * @throws HibernateException
                  */

                  public static Session currentSession() throws HibernateException {       
                          Session s = (Session) sessionThread.get();               
                          if (s == null) {
                                  if (sf == null) sf = new Configuration().configure().buildSessionFactory();       
                                  s = sf.openSession();
                                  sessionThread.set(s);               
                          }
                          return s;
                  }

                  /**
                  * 獲取一個新的Session
                  *
                  * @return Session
                  * @throws HibernateException
                  */

                  public static Session newSession() throws HibernateException {       
                 
                          if (sf == null) sf = new Configuration().configure().buildSessionFactory();       
                          Session s = sf.openSession();
                          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();
                  }

                  /**
                  * 回滾當前事務
                  *
                  * @throws HibernateException
                  */

                  public static void rollbackTransaction() throws HibernateException {
                          Transaction tx = (Transaction) transactionThread.get();
                          transactionThread.set(null);
                          if (tx != null) tx.rollback();
                  }
                         
                  /**
                  * 關閉當前線程使用的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 {
                                  String conf = "hibernate.cfg.xml";
                                  if (args.length != 0) conf = args[0];
                                  Configuration cfg = new Configuration().configure("/" + conf);
                                  SchemaExport se = new SchemaExport(cfg);
                                  //se.setOutputFile("create_table.sql");
                                  se.create(true,true);
                          } catch (HibernateException e) {                       
                                  System.out.println(e.getMessage());
                          }
                         
                  }
          }



          在你的DAOImpl中,你直接:

          java代碼: 


          Session session = HibernateSession.currentSession();
          HibernateSession.currentTransaction();
          .....
          session.flush();


          事務的提交和Session的close都在Filter里面完成,Filter里面代碼如下:

          java代碼: 

                          try {
                                  HibernateSession.commitTransaction();
                          } catch (HibernateException e) {               
                                  try {
                                          HibernateSession.rollbackTransaction();
                                  } catch (HibernateException e1) {
                                          System.out.println(e1.getMessage());
                                  }       
                                  System.out.println(e.getMessage());
                          } finally {
                                  try {
                                          HibernateSession.closeSession();
                                  } catch (HibernateException e) {
                                          System.out.println(e.getMessage());
                                  }
                          }



          這是粗顆粒度的Transaction。

          如果該DAO需要一個細顆粒度的事務的話,那么你就

          java代碼: 


          Session session = HibernateSession.currentSession();
          HibernateSession.currentTransaction();
          .....
          session.flush();
          HibernateSession.commitTransaction();


          這樣就可以實現一個細顆粒度的事務,而且在該線程執行序列中,接下去的另一個方法調用也是類似:

          java代碼: 


          Session session = HibernateSession.currentSession();
          HibernateSession.currentTransaction();
          .....
          session.flush();


          這樣的代碼,而HibernateSession.currentTransaction();會自己檢查當前是否已經啟動事務,如果發現沒有啟動事務,那么就會新啟動一個事務的。

          因此,如果你需要細顆粒度的事務的話,就在你方法里面
          java代碼: 

          HibernateSession.commitTransaction();

          如果你不需要細顆粒度事務的話,就不寫這句代碼就OK了,最后Filter會提交。
          posted on 2005-03-15 20:16 笨笨 閱讀(937) 評論(0)  編輯  收藏 所屬分類: HibernateAndSpring 、ALL
          主站蜘蛛池模板: 宜昌市| 金堂县| 平阳县| 永昌县| 仁化县| 汝南县| 台湾省| 乳源| 法库县| 济源市| 龙游县| 马鞍山市| 邵阳县| 辰溪县| 华容县| 缙云县| 呼伦贝尔市| 永宁县| 裕民县| 和田市| 麻阳| 固始县| 闸北区| 太保市| 百色市| 宿松县| 甘孜| 湘潭县| 门头沟区| 松潘县| 长海县| 衡阳县| 景泰县| 仪征市| 潞西市| 贵南县| 莆田市| 太仓市| 延寿县| 通河县| 陈巴尔虎旗|