kapok

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

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            455 隨筆 :: 0 文章 :: 76 評(píng)論 :: 0 Trackbacks
          http://forum.javaeye.com/viewtopic.php?t=4588&highlight=threadlocal




          wes109 寫(xiě)道:
          ThreadLocal可以解決一定的事務(wù)問(wèn)題
          但在Web應(yīng)用中,我發(fā)現(xiàn)在filter里面close連接無(wú)疑是最合適的

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

          并且用ThreadLocal實(shí)現(xiàn)的也只是粗粒度的事務(wù),尤其是在B/S應(yīng)用中

          ThreadLocal,雞肋? Question


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

          事務(wù)的scope是在Session的scope里面的,你都已經(jīng)close了Session了,當(dāng)然不會(huì)在一個(gè)事務(wù)里面了。

          你怎么知道是粗粒度,那是你不會(huì)用,你就不會(huì)把Transaction也放到ThreadLocal里面,實(shí)現(xiàn)細(xì)粒度的事務(wù)控制嗎?貼段代碼給你參考:

          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;
                 
                  /**
                  * 獲取當(dāng)前線程使用的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;
                  }

                  /**
                  * 獲取一個(gè)新的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;
                  }
                         
                  /**
                  * 啟動(dòng)或者加入當(dāng)前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;
                  }
                 
                  /**
                  * 提交當(dāng)前Session的Transaction
                  *
                  * @throws HibernateException
                  */

                  public static void commitTransaction() throws HibernateException {
                          Transaction tx = (Transaction) transactionThread.get();
                          transactionThread.set(null);
                          if (tx != null) tx.commit();
                  }

                  /**
                  * 回滾當(dāng)前事務(wù)
                  *
                  * @throws HibernateException
                  */

                  public static void rollbackTransaction() throws HibernateException {
                          Transaction tx = (Transaction) transactionThread.get();
                          transactionThread.set(null);
                          if (tx != null) tx.rollback();
                  }
                         
                  /**
                  * 關(guān)閉當(dāng)前線程使用的Session
                  *
                  * @throws HibernateException
                  */

                  public static void closeSession() throws HibernateException {                       
                          Session s = (Session) sessionThread.get();               
                          sessionThread.set(null);
                          if (s != null) s.close();
                  }

                  /**
                  * 根據(jù)映射文件和持久對(duì)象生成數(shù)據(jù)庫(kù)DDL,生成文件為create_table.sql
                  *
                  * @param args 參數(shù)
                  */

                  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();


          事務(wù)的提交和Session的close都在Filter里面完成,F(xiàn)ilter里面代碼如下:

          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需要一個(gè)細(xì)顆粒度的事務(wù)的話,那么你就

          java代碼: 


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


          這樣就可以實(shí)現(xiàn)一個(gè)細(xì)顆粒度的事務(wù),而且在該線程執(zhí)行序列中,接下去的另一個(gè)方法調(diào)用也是類似:

          java代碼: 


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


          這樣的代碼,而HibernateSession.currentTransaction();會(huì)自己檢查當(dāng)前是否已經(jīng)啟動(dòng)事務(wù),如果發(fā)現(xiàn)沒(méi)有啟動(dòng)事務(wù),那么就會(huì)新啟動(dòng)一個(gè)事務(wù)的。

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

          HibernateSession.commitTransaction();

          如果你不需要細(xì)顆粒度事務(wù)的話,就不寫(xiě)這句代碼就OK了,最后Filter會(huì)提交。
          posted on 2005-03-15 20:16 笨笨 閱讀(937) 評(píng)論(0)  編輯  收藏 所屬分類: HibernateAndSpringALL
          主站蜘蛛池模板: 辽阳县| 鄄城县| 运城市| 建瓯市| 大丰市| 锦屏县| 志丹县| 巴林右旗| 新平| 庄河市| 上高县| 新巴尔虎右旗| 济宁市| 招远市| 淄博市| 万安县| 连江县| 历史| 新源县| 皋兰县| 汝城县| 监利县| 陇川县| 大田县| 水城县| 剑阁县| 黎城县| 台东市| 泸溪县| 辽中县| 孟州市| 瓦房店市| 昂仁县| 乐安县| 万源市| 宜宾市| 色达县| 中山市| 乌兰县| 鞍山市| 陵水|