Spring 在MultiTenantConnectionProvider中引发异常,将耗尽连接池中的连接
我在MySQL中使用多租户模式作为Spring 在MultiTenantConnectionProvider中引发异常,将耗尽连接池中的连接,spring,hibernate,spring-boot,multi-tenant,Spring,Hibernate,Spring Boot,Multi Tenant,我在MySQL中使用多租户模式作为 class SchemaPerTenantConnectionProvider : MultiTenantConnectionProvider { @Autowired private lateinit var dataSource: DataSource @Throws(SQLException::class) override fun getAnyConnection() = this.dataSource.connection
class SchemaPerTenantConnectionProvider : MultiTenantConnectionProvider {
@Autowired
private lateinit var dataSource: DataSource
@Throws(SQLException::class)
override fun getAnyConnection() = this.dataSource.connection
@Throws(SQLException::class)
override fun releaseAnyConnection(connection: Connection) {
connection.close()
}
@Throws(SQLException::class)
override fun getConnection(tenantIdentifier: String): Connection {
val connection = this.anyConnection
try {
connection.createStatement().execute("USE $tenantIdentifier ")
} catch (e: SQLException) {
throw SQLException("Could not alter JDBC connection to schema [$tenantIdentifier]")
}
return connection
}
...
}
我的连接池大小是10,现在如果任何无效的tenantIdentifier
被传递了10次,那么10个连接将耗尽,之后应用程序将无法获取任何连接
尝试抛出异常,HibernateeException,但没有帮助。使用与
默认架构的连接将获取错误的结果。在getConnection()
中有没有一种方法可以处理这种情况,以避免耗尽连接限制 下面的配置应该可以工作,重写public void releaseConnection(String tenantIdentifier,Connection Connection)
将确保连接被释放回连接池
public class MultiTenantConnectionProviderImpl
implements MultiTenantConnectionProvider, Stoppable {
private final ConnectionProvider connectionProvider = ConnectionProviderUtils.buildConnectionProvider( "master" );
@Override
public Connection getAnyConnection() throws SQLException {
return connectionProvider.getConnection();
}
@Override
public void releaseAnyConnection(Connection connection) throws SQLException {
connectionProvider.closeConnection( connection );
}
@Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
final Connection connection = getAnyConnection();
try {
connection.createStatement().execute( "USE " + tenanantIdentifier );
}
catch ( SQLException e ) {
throw new HibernateException(
"Could not alter JDBC connection to specified schema [" +
tenantIdentifier + "]",
e
);
}
return connection;
}
@Override
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
try {
connection.createStatement().execute( "USE master" );
}
catch ( SQLException e ) {
// on error, throw an exception to make sure the connection is not returned to the pool.
// your requirements may differ
throw new HibernateException(
"Could not alter JDBC connection to specified schema [" +
tenantIdentifier + "]",
e
);
}
connectionProvider.closeConnection( connection );
}
...
}
接下来,在spring boot中微调数据源配置:
# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.tomcat.max-wait=10000
# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=50
参考:
如果问题仍然存在,请继续使用数据源连接池机制支持,如Hikari等。关闭连接,以防出现错误解决问题
@Throws(SQLException::class)
override fun getConnection(tenantIdentifier: String): Connection {
val connection = this.anyConnection
try {
connection.createStatement().execute("USE $tenantIdentifier ")
} catch (e: SQLException) {
connection.close()
throw SQLException("Could not alter JDBC connection to schema [$tenantIdentifier]")
}
return connection
}
我希望您也重写public void releaseConnection(String tenantIdentifier,Connection Connection)
并关闭此处的连接谢谢您的回答。实际上,正如您所提到的,我正在使用HikariCP并在releaseConnection中释放连接。这不管用。现在我尝试关闭getConnection()中的连接,但出现错误,解决了问题OK很棒,但不需要关闭getConnection()中的连接。即使在获取连接时引发异常,调用方也肯定会调用releaseConnection方法。请仔细检查releaseConnection方法,该方法将关闭连接实例。