当前位置: 首页 > 知识库问答 >
问题:

Hibernate在多线程应用程序中随机抛出“org.Hibernate.exception.jdbcConnectionException:不能打开连接”

姬阳曜
2023-03-14
public class HibernateUtil {

private static SessionFactory INSTANCE_SESSION_FACTORY = null;

public enum Common {
    SUCCESS, ROLLBACK
}

private synchronized static void createSessionFactory() {
    try {
        if (INSTANCE_SESSION_FACTORY != null) {
            return;
        }
        ResourceBundle rb = ResourceBundle.getBundle("application");
        Integer environment = Integer.valueOf(rb.getString("environment"));

        Properties prop = new Properties();

        switch (environment) {
        /* LOCAL */
        case 1:
            prop.setProperty("hibernate.connection.driver_class", rb.getString("hibernate.driver.class.name"));
            prop.setProperty("hibernate.connection.url", rb.getString("hibernate.db.uri"));
            prop.setProperty("hibernate.connection.username", rb.getString("hibernate.db.username"));
            prop.setProperty("hibernate.connection.password", rb.getString("hibernate.db.password"));
            break;
        default:
            throw new ConfigurationException(environment == null ? "No environment added in application.properties"
                    : "Wrong environment added in application.properties");
        }

        prop.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
        prop.setProperty("hibernate.show_sql", "true");
        prop.setProperty("hibernate.hbm2ddl.auto", "update");
        prop.setProperty("hibernate.current_session_context_class", "thread");
        prop.setProperty("hibernate.connection.pool_size", "100");

        prop.setProperty("hibernate.c3p0.minPoolSize", "5");
        prop.setProperty("hibernate.c3p0.maxPoolSize", "100");
        prop.setProperty("hibernate.c3p0.initialPoolSize", "10");
        prop.setProperty("hibernate.c3p0.timeout", "1800");
        prop.setProperty("hibernate.c3p0.max_statements=", "50");

        org.hibernate.cfg.Configuration config = new org.hibernate.cfg.Configuration().addProperties(prop)
                .addAnnotatedClass(Account.class).addAnnotatedClass(InsynctiveProperty.class)
        serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties())
        .buildServiceRegistry();
        INSTANCE_SESSION_FACTORY = config.buildSessionFactory(serviceRegistry);
    } catch (Throwable ex) {
        System.err.println("Initial SessionFactory creation failed." + ex);
        throw new ExceptionInInitializerError(ex);
    }
}

public static SessionFactory getSessionFactory() {
    if (INSTANCE_SESSION_FACTORY == null) {
        createSessionFactory();
    }
    return INSTANCE_SESSION_FACTORY;
}

public static Session getCurrentSession() {
    return getSessionFactory().getCurrentSession();
}

public static Session openSession() {
    return getSessionFactory().openSession();
}

public static void closeCurrentSession() {
    getSessionFactory().getCurrentSession().close();
}

public synchronized static Object get(Class<?> clazz, Integer id) {
    Session session = getCurrentSession();
    final Transaction transaction = session.beginTransaction();
    try {
        Object obj = session.get(clazz, id);
        transaction.commit();
        return obj;
    } catch (RuntimeException ex) {
        System.out.println(ex);
        transaction.rollback();
        throw ex;
    } finally {

    }
}

public Common save(Object object) {
    Session session = openCurrentSession();
    Transaction transaction = null;
    Common result = null;
    try {
        transaction = openTransaction(session);
        session.save(object);
        transaction.commit();
        result = Common.SUCCESS;
    } catch (Exception e) {
        e.printStackTrace();
        if (transaction != null) {
            transaction.rollback();
        }
        result = Common.ROLLBACK;
    } finally {
        session.close();
    }

    return result;
}

public Common update(Object object) {
    Session session = openCurrentSession();
    Transaction transaction = null;
    Common result;

    try {
        transaction = openTransaction(session);
        session.update(object);
        transaction.commit();
        result = Common.SUCCESS;
    } catch (Exception e) {
        e.printStackTrace();

        if (transaction != null) {
            transaction.rollback();
        }
        result = Common.ROLLBACK;
    } finally {
        session.close();
    }
    return result;
}

public Session openCurrentSession() {
    return getSessionFactory().openSession();
}

public Transaction openTransaction(Session session) {
    return session.beginTransaction();
}
}

有时,当使用这些mehtods之一时,我会重复出现此错误:

else if ( CONNECTION_CATEGORIES.contains( sqlStateClassCode ) ) {
                    return new JDBCConnectionException( message, sqlException, sql );

注意,我使用的是Heroku数据库(ClearDB,MySQL),当我使用本地数据库时,我不能重现这个错误。

共有1个答案

宇文卓
2023-03-14

您已经实现了双重检查锁定模式。为了使其正常工作,必须使instance_session_factory变量volatile

注意,这可能是也可能不是异常的原因,但它肯定是代码中的bug。

更新:

您可能只是遇到了池连接超时的情况。您可能希望尝试启用C3P0的空闲连接检查(类似于“idleConnectionTestPeriod=300”)。

 类似资料:
  • 我的主文件app.js连接到userDB我想添加第二个数据库postsDB 常量mongoose=require(“mongoose”); 常量app=express(); mongoose.set(“UseCreateIndex”,true);mongoose.set(“UseUnifiedTopology”,true); Mongoose.connect(“MongoDB://localhos

  • 问题内容: 我正在尝试将Hibernate用于多线程应用程序,其中每个线程都检索一个对象并将其插入表中。我的代码如下所示。我每个线程都有本地hibernate会话对象,在每个InsertData中,我都执行beginTransaction和commit。 我面临的问题是很多次我收到“ org.hibernate.TransactionException:不支持嵌套事务” 由于我是hibernate

  • 我正在用mssql数据库开发一个java Spring Hibernate应用程序。但是我无法与mssql数据库建立连接。 [请求处理失败;嵌套异常为org.springframework.transaction.CanNotCreateTransactionException:无法打开事务的Hibernate会话;嵌套异常为org.Hibernate.exception.GenericJDBcE

  • 我正在使用spring hibernate开发一个应用程序,如果我使用的是199.892.2.345这样的数据库,我就可以连接到该数据库并执行cud操作,但是如果我将其更改为spring config中的Vinayaka.cloudapp.net,111这样的云数据库,我会得到下面的错误,下面是我正在使用的spring config文件, 错误

  • 问题内容: 在多线程应用程序中如何使用Hibernate(例如,每个客户端连接在服务器上启动它自己的线程)。 EntityManager应该仅由EntityManagerFactory创建一次,例如: 还是我必须为每个线程以及关闭EM的每个事务重新创建实体? 我的CRUD方法如下所示: 我要不要每次都跑?还是因为每个人都使用自己的缓存创建自己的EntityManager实例而使我陷入麻烦了? 问题

  • 问题内容: 为了在Linux上开发高度网络密集型服务器应用程序,首选哪种架构?这个想法是,该应用通常可以在具有多个内核(虚拟或物理)的机器上运行。考虑到性能是关键标准,选择多线程应用程序还是采用多进程设计更好?我确实知道资源共享和从多个进程访问此类资源的同步是很多编程开销,但是如前所述,整体性能是关键要求,因此我们可以忽略这些事情。编程语言为C / C ++。 我听说,即使是多线程应用程序(单个进