天天看點

開發時資料庫連接配接失敗的解決辦法

在開發過程中,突然發現自己和周圍的小夥伴總有一定的機率連接配接不上,并且機會很随機,提示如下錯誤:

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Unable to open JDBC connection for schema management target
    at org.hibernate.tool.schema.internal.TargetDatabaseImpl.prepare(TargetDatabaseImpl.java:)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:)
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:)
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:)
    ...  common frames omitted
Caused by: java.sql.SQLException: Error preloading the connection pool
    at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:)
    at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:)
    at org.hibernate.tool.schema.internal.TargetDatabaseImpl.prepare(TargetDatabaseImpl.java:)
    ...  common frames omitted
Caused by: java.sql.SQLNonTransientConnectionException: Could not create connection to database server.
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:)
    at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:)
    at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:)
    at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:)
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:)
    at org.apache.commons.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:)
    at org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:)
    at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:)
    at org.apache.commons.pool2.impl.GenericObjectPool.addObject(GenericObjectPool.java:)
    at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:)
    ...  common frames omitted
Caused by: java.lang.ArrayIndexOutOfBoundsException: null
           

用Navicat for MySQL連接配接資料庫,卻又一切正常,不合理啊!

“ArrayIndexOutOfBoundsException”,又是一個不正常的現象,連接配接資料庫,跟數組還有關系嗎?什麼時候資料庫連接配接還需要數組呢?什麼時候數組還會越界呢?

繼續看異常,還發現了“commons.pool2”的身影,那問題就很好解決了,找到連接配接池的配置檔案,如下:

<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="initialSize" value="50"/>
    <property name="maxIdle" value="50"/>
    <property name="maxWaitMillis" value="10000"/>
    <property name="maxTotal" value="100" />
</bean> 
           

那問題在哪裡呢?啟動時報錯,隻可能是initialSize的問(還有createDataSource的明證),将其改為10,送出代碼管理庫,再次啟動,一切正常!

結論

在開發過程中,開發資料庫的連接配接數量是有限的,大家一起申請大量的初始連接配接池,必然會導緻資料庫連接配接不夠用。