我想为我们的Java EE软件使用多租户架构。 我们使用WildFly 8.2(带有Hibernate 4.3.7的JPA)和PostgreSQL 9.3
我知道Hibernate为多租户提供了一些API:http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch16.html
我们可以将它与JPA集成在persistence.xml文件中,如下所示:
<property name="hibernate.multiTenancy" value="SCHEMA"/>
<property name="hibernate.tenant_identifier_resolver" value="mycompany.hibernate.multitenant.SchemaResolver"/>
<property name="hibernate.multi_tenant_connection_provider" value="mycompany.hibernate.multitenant.MultiTenantProvider"/>
但是我的“hibernate.multi_tenant_connection_provider”存在一些问题。
我想使用WildFly配置(standalone.xml)中的数据源池,但是如果我使用它,则会导致池中的连接泄漏。 连接永远不会释放到池中。
我是否需要使用其他库来管理我的数据库连接池,如C3P0?我虽然WildFly可以正确管理它。 是否有更好的方法将多租户与JPA集成?
或者我的JNDI查找可能有问题吗?
如果我使用SCHEMA进行多租户配置,那么连接总是连接到同一个数据库/数据源,那么为什么我们需要编写一些连接提供程序呢?
你有什么想法吗? 提前感谢您的帮助。
public class MultiTenantProvider implements MultiTenantConnectionProvider {
@Override
public boolean supportsAggressiveRelease() {
return false;
}
@Override
public boolean isUnwrappableAs(Class clazz) {
return false;
}
@Override
public <T> T unwrap(Class<T> clazz) {
return null;
}
@Override
public Connection getAnyConnection() throws SQLException {
Context initContext;
Connection connection = null;
try {
initContext = new InitialContext();
DataSource ds = (DataSource) initContext.lookup("java:/MyPostgresDS");
connection = ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
}
return connection;
}
@Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
final Connection connection = getAnyConnection();
try {
connection.createStatement().execute("SET SCHEMA '" + tenantIdentifier + "'");
}
catch (SQLException e) {
throw new HibernateException("Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]", e);
}
return connection;
}
@Override
public void releaseAnyConnection(Connection connection) throws SQLException {
try {
connection.createStatement().execute("SET SCHEMA 'public'");
}
catch (SQLException e) {
throw new HibernateException("Could not alter JDBC connection to specified schema [public]", e);
}
connection.close();
}
@Override
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
releaseAnyConnection(connection);
}
}
WildFly的standalone.xml文件中的数据源
<datasource jndi-name="java:/MyPostgresDS" pool-name="MyPostgresDS" enabled="true" use-java-context="true">
<connection-url>jdbc:postgresql:demo</connection-url>
<driver>posgresqlDriver</driver>
<pool>
<min-pool-size>10</min-pool-size>
<max-pool-size>50</max-pool-size>
<prefill>true</prefill>
</pool>
<security>
<user-name>postgres</user-name>
<password>postgres</password>
</security>
<timeout>
<blocking-timeout-millis>20000</blocking-timeout-millis>
<idle-timeout-minutes>5</idle-timeout-minutes>
</timeout>
</datasource>
答案 0 :(得分:0)
这个问题没有完美的解决方案。你需要尝试几件事。如果Wildfly保持打开状态,它就无法正常释放空闲连接。
解决步骤
SELECT datname,pid,usename,waiting,state,(now() - query_start)AS 因为,(now() - state_change)AS since2,(now() - backend_start)as since3,(now() - xact_start)as4,查询FROM pg_stat_activity 自订单开始;
B
同时定义刷新策略
<timeout><idle-timeout-minutes>1</idle-timeout-minutes></timeout>
记录wildfly连接:http://www.javacodegeeks.com/2014/11/tomcat-wildfly-configuring-database-connectivity.html
如果你能够使用http://www.mastertheboss.com/jbossas/wildfly9/detecting-connection-leaks-in-wildfly-9
,你可以找到它答案 1 :(得分:0)
@Override
public boolean supportsAggressiveRelease() {
return true; // changing this true from false will fix the leak.
}