【问题标题】:Hibernate problem: "Too many connections"休眠问题:“连接太多”
【发布时间】:2011-08-24 23:48:07
【问题描述】:

我收到以下错误:

.
.
.
.
6844 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1040, SQLState: 08004
6844 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Data source rejected establishment of connection,  message from server: "Too many connections"
Exception in thread "main" org.hibernate.exception.JDBCConnectionException: Cannot open connection
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:99)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52)
    at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449)
    at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
    at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:160)
    at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:81)
    at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473)
    at sun.reflect.GeneratedMethodAccessor121.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:345)
    at $Proxy0.beginTransaction(Unknown Source)
    at com.mycomp.myproj.matcher.Matcher.findMatch(Matcher.java:228)
    at com.mycomp.myproj.Confidence.Confidence.main(Confidence.java:160)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection,  message from server: "Too many connections"
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    at com.mysql.jdbc.Util.getInstance(Util.java:384)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
    at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1105)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2186)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:787)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:49)
    at sun.reflect.GeneratedConstructorAccessor16.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:357)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133)
    at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
    ... 11 more

我的程序的休眠位是这样的:

for loop_1        // this will execute say 2000 times 
{
    for loop_2       // this will execute say 1000 times
    {
        // Opening 2 sessions for 2 different databases

        Configuration config_1 = new Configuration().configure("Hibernate_1.cfg.xml");
        SessionFactory sessionFactory_1 = config_1.buildSessionFactory();
        Session session_1 = sessionFactory_1.getCurrentSession();
        session_1.beginTransaction();

        Configuration config_2 = new Configuration().configure("Hibernate_2.cfg.xml");
        SessionFactory sessionFactory_2 = config_2.buildSessionFactory();
        Session session_2 = sessionFactory_2.getCurrentSession();
        session_2.beginTransaction();

        doInsertDb_1(some_object_1, session_1);

        doUpdateDb_2(some_object_2, session_2);
    }
}

    public int doInsertDb_1(Object obj, Session session) {

        try {

            session.save(obj);
            session.flush();
            session.getTransaction().commit();

            return 1;

        } catch (Exception ex) {
            ex.printStackTrace();
            return 0;
        }
    }

    public int doUpdate_2(Object obj, Session session) {

        try {

            Query query = session.createQuery("" <Creating some query> );
            query.executeUpdate();
            session.getTransaction().commit();

            return 1;

        } catch (Exception ex) {
            ex.printStackTrace();
            return 0;
        }
    }

很明显,在某处我没有正确关闭连接。我无法弄清楚在哪里?有人可以指导我吗?

非常感谢。

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    您确定每次循环都需要创建两个会话吗?在两个循环之前创建一次它们可能会解决您的问题并加速您的代码。但是,如果您坚持在内部循环中打开它们,请确保在之后close() 它们,因为这至少应该释放您正在打开的数据库连接(但永远不会关闭。)

    编辑:您应该推迟提交更改,直到完成所有更改,以免过早关闭连接。

    编辑 2:由于您需要每次更新的结果来处理进一步的更新,您至少可以将 SessionFactories 的创建移到循环之外。

    【讨论】:

    • @dlev:感谢您的回复。当我回复 Cris 时,如果我在 for loop_1 之外创建它们,我会收到 Session already closed! 错误。这是因为当我执行session.getTransaction().commit(); 时,我可以在调试器中看到它在此 stmt 之后关闭会话。
    • 有趣。也许您应该在完成所有更改之前推迟提交?
    • 我一定会尝试的。在某处我发现关闭 Statement 和 ResultSet 帮助了提问者。我还在每个循环中做一些选择(我没有在我的问题中添加)。所以认为这就是问题所在。但我也关闭了 Statement 和 ResultSet,但仍然是同样的问题。
    • @dlev:您的建议有帮助,但有一个问题。在循环中,当我在数据库中插入记录时,我必须在下一个循环中考虑该记录。因此,如果我不立即提交,我将无法获得该记录,因此最终输出是错误的。有没有更好的办法?
    • 嗯...一种可能性是将 SessionFactory 创建移到两个循环之外,但将 Session 创建本身保留在内部。这行得通吗?
    【解决方案2】:

    尝试在循环之外创建会话

    【讨论】:

    • 感谢您的回复。我试图在for loop_2 之外创建它们,但我得到了同样的错误。另外,我尝试在for loop_2 之外创建它们,我得到Session already closed!,这是预期的。
    • 我在循环外创建了会话,还删除了session.getTransaction().commit(); stmt,我现在在for loop_1 之外提交事务。但是当我在数据库中插入记录时,我必须在下一个循环中考虑该记录。因此,如果我不立即提交,我将无法获得该记录,因此最终输出是错误的。有没有更好的办法?
    猜你喜欢
    • 2016-04-20
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多