http://forum.javaeye.com/viewtopic.php?t=4588&highlight=threadlocal
你為什么要在其他地方close呢?
事務(wù)的scope是在Session的scope里面的,你都已經(jīng)close了Session了,當(dāng)然不會(huì)在一個(gè)事務(wù)里面了。
你怎么知道是粗粒度,那是你不會(huì)用,你就不會(huì)把Transaction也放到ThreadLocal里面,實(shí)現(xiàn)細(xì)粒度的事務(wù)控制嗎?貼段代碼給你參考:
在你的DAOImpl中,你直接:
事務(wù)的提交和Session的close都在Filter里面完成,F(xiàn)ilter里面代碼如下:
這是粗顆粒度的Transaction。
如果該DAO需要一個(gè)細(xì)顆粒度的事務(wù)的話,那么你就
這樣就可以實(shí)現(xiàn)一個(gè)細(xì)顆粒度的事務(wù),而且在該線程執(zhí)行序列中,接下去的另一個(gè)方法調(diào)用也是類似:
這樣的代碼,而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ù)的話,就在你方法里面
如果你不需要細(xì)顆粒度事務(wù)的話,就不寫(xiě)這句代碼就OK了,最后Filter會(huì)提交。
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,雞肋? ![]() |
你為什么要在其他地方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(); |