Hibernate 在多线程下 获取唯一的SessionFactory
Hibernate 在多线程下 获取唯一的SessionFactory
古世界 发表于4年前
Hibernate 在多线程下 获取唯一的SessionFactory
  • 发表于 4年前
  • 阅读 360
  • 收藏 0
  • 点赞 7
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 在一个项目中Hibernate的SessionFactory只允许被创建一次, 原因是如果你使用了c3p0这样的数据库连接池, 每一个SessionFactory都保存了最小连接数, 连接数会逐渐增多也就失去了连接池的意义, 那么如何避免多线程造成多次创建SessionFactory, 下面就来说一下我在项目中碰到的问题

Hibernate 在多线程下 获取唯一的SessionFactory

    背景:  在项目中使用了Hibernate, 连接池用的是c3p0, 最小连接数设置为5, 问题来了, 每当登录系统后, 在数据库中查看连接数就会发现有10个session连接, 这让我很是苦恼, 经过debug发现在开始登录的时候, 页面会同时发出两个ajax请求, 请求后台数据的数据, 这个时候在后台就会有两个线程同时去请求HibernateUtil创建SessionFactory(当然这个时候就是SessionFactory的初始化), 在没有线程同步的情况下, 两个线程就会使HibernateUtil初始化出两个SessionFactory, 这样每个SessionFactory都会保持5个最小连接数, 那么在数据库端就会看到有10个session连接了, 忘了介绍web容器使用的是tomcat.

    解决方案: 发现问题了, 当然解决方案也就有了, 两种法案: 1.既然是多线程的问题, 那就设置线程同步好了,但是感觉这样有点不太优雅; 2. 如果我在ajax请求还没访问后台之前, 就将SessionFactory初始化好了, 也就不会多线程同时请求初始化SessionFactory的问题了;

   贴一下代码看看吧: (为了确保安全, 我两种方案都使用了)

public class HibernateUtil {

    private static SessionFactory sessionFactory = null;
    
    private static Configuration config =
            new Configuration().configure("hibernate.cfg.xml");

    static {  //此处就是第二中解决方案, 当类加载的时候就初始化好SessionFactory
        configureSessionFactory();
    }

    /**
     * 创建SessionFactory, 此方法加了锁, 就是为了线程同步
     */
    private synchronized static void configureSessionFactory () throws HibernateException {
        if(sessionFactory != null && !sessionFactory.isClosed()){
            return;
        }
        // 以下这两句就是4.3的新用法
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .applySettings(config.getProperties());
        ServiceRegistry registry = builder.build();
        sessionFactory = config.buildSessionFactory(registry);
    }

    /**
     * 获取sessionFactory
     * @return sessionFactory
     */
    public static SessionFactory getSessionFactory() {
        if(sessionFactory == null || sessionFactory.isClosed()){
            configureSessionFactory();
        }
        return sessionFactory;
    }
}

以上就是此次问题的解决方案, 但是我有一事想不通, SessionFactory变量本身属于HibernateUtil的静态变量, 可是为什么当多线程同时请求初始化SessionFactory时, 会初始化出两个SessionFactory呢, 难道HibernateUtil本身在内存中就有两份? 本人菜鸟一个, 还请高手大神们指教一二, 不胜感激 ... ...

共有 人打赏支持
粉丝 12
博文 20
码字总数 6590
×
古世界
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: