我在MySQL中使用模式的多租户,
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个连接用尽,此应用程序无法获取任何连接。
尝试投掷Exception, HibernateException
并没有帮助。使用与default schema
的连接将获取错误的结果。有没有办法在getConnection()
中处理这种情况,以免耗尽连接限制?
答案 0 :(得分:2)
以下配置应该有效,覆盖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等。
答案 1 :(得分:0)
关闭连接,如果错误解决了问题。
@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
}