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 笨笨 阅读(932) 评论(0)  编辑  收藏 所属分类: HibernateAndSpringALL

只有注册用户登录后才能发表评论。


网站导航: