java - 如何以编程方式确定连接池大小?

标签 java mysql hibernate connection-pooling c3p0

有没有办法以编程方式确定数据库连接池大小(已使用的连接/连接池中剩余的连接)?我们将 Hibernate 与 C3P0 结合使用。

我们在连接到数据库时遇到问题。抛出以下异常,数据未保存在数据库中。

1005,MA,19/09/11 09:39:14,com.novosys.gtw.business.frontend.SnapshotMessageBusiness.save, Major: Cannot open connection
org.hibernate.exception.GenericJDBCException: Cannot open connection
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
    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:142)
    at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
    at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1354)
    at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:342)
    at $Proxy0.beginTransaction(Unknown Source)
    at com.novosys.gtw.util.base.BaseBusiness.save(BaseBusiness.java:199)
    at com.novosys.gtw.business.backend.receivesnapshotmessage.filter.SaveMessageFilter.decode(SaveMessageFilter.java:102)
    at org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory$ProtocolDecoderImpl.doDecode(DemuxingProtocolCodecFactory.java:292)
    at org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:133)
    at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:158)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
    at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
    at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
    at com.novosys.gtw.business.backend.receivesnapshotmessage.filter.WhitelistFilter.messageReceived(WhitelistFilter.java:231)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
    at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
    at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
    at com.novosys.gtw.business.backend.receivesnapshotmessage.filter.MoniterFilter.messageReceived(MoniterFilter.java:92)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
    at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
    at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
    at org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java:220)
    at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:264)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
    at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
    at java.lang.Thread.run(Thread.java:595)
Caused by: java.sql.SQLException: Connections could not be acquired from the underlying database!
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:529)
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
    at org.hibernate.connection.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:78)
    at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
    ... 31 more
Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source.
    at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1319)
    at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
    ... 34 more

We tried to resolve it by increasing connection pool size and also increasing no. of connections available at MySQL level, but of no use. We are now trying to sort of debug it to see if its due to connection pool size or due to MySQL connection size. We want to log no. of connection available/in use in connection pool size but could not get any help from google.

Environment: Java, Hibernate, C3P0, MySQL

Session session = null;
Transaction transaction = null;

try {
            session = HibernateUtil.getSessionFactory(datasource).getCurrentSession();
            transaction = session.beginTransaction();
            // db save called here
            session.getTransaction().commit();
        } catch (Exception e) {
            Logger.write(LoggerConstant.MAJOR_ERROR, e.getMessage(), e, methodName);
        } finally {
            try {
                if ((transaction != null) && (transaction.isActive())) {
                    transaction.rollback();
                }
            } catch (Exception e) {
                Logger.write(LoggerConstant.CRITICAL_ERROR, e.getMessage(), e, methodName);
            }
            try {
                if ((session != null) && (session.isOpen())) {
                    session.close();
                }
            } catch (Exception e) {
                Logger.write(LoggerConstant.CRITICAL_ERROR, e.getMessage(), e, methodName);
            }
        }

最佳答案

我不认为您的问题是连接池本身,而是更普遍的连接泄漏。此问题通常与 HibernateDaoSupport.getSession() 的使用没有与 HibernateDaoSupport.releaseSession() 正确配对有关。一般来说,你想要类似的东西

public SomeObject getSomething() 
{ 
    Session session = null;
    try 
    {
        session = this.getSession();
        Query query = session.createSQLQuery("SELECT * FROM SomeTable WHERE SomeClause").addEntity(SomeObject.class); 

        // extract object from query 

        return someObject; 
    } 
    finally 
    {
        if (session != null) 
            this.releaseSession(session);
    }        
}

这可以通过使用 HibernateCallback 自动完成。您可以通过向 this.getHibernateTemplate().executeFind 提供查询来执行此操作,这将在 Hibernate 中使用具有自动资源管理的 session 。

关于java - 如何以编程方式确定连接池大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7495077/

相关文章:

java - 将元素添加到模拟列表

java - 不同事件线程之间的死锁

php - 如何一次更改所有学生的年级

php - 即使辅助表不适用,也会在一个查询中从多个表返回数据

带枚举的 Hibernate 查找表

java - 如何使用 java.text.MessageFormat 格式化小数百分比

java - 如何连续读取时间?

jquery - cakephp中是否有任何常见的默认函数fpr APPmodel ..在查询执行之前运行

java - Hibernate:通过注释具有动态表名的数据对象

java - JPA Hibernate::实体的继承,带有附加的 OneToMany 列表