2015-04-14 48 views
0

我想为我们的Java EE软件使用多租户架构。 我们使用WildFly 8.2(JPA与Hibernate 4.3.7)在PostgreSQL 9.3多租户软件中的WildFly/JPA数据库连接泄漏

我知道休眠的多租户提供了一些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

没有人可以帮我这个发现泄漏? :( – nico2324325

回答

0

还有就是这个问题没有完美的解决方案。你需要尝试几件事情。如果Wildfly一直保持打开状态,则无法正确释放闲置连接。

步骤来解决它保持连接打开

  1. 查找查询:由于您使用的是Postgres使用此查询找到哪个查询保持连接打开。如果您发现查询半工作完成。

SELECT datname,PID,USENAME等待状态,(今() - query_start)AS 以来,(现在的() - state_change)AS since2,(现在是() - backend_start)作为 since3 ,(now() - xact_start)as since4,查询FROM pg_stat_activity ORDER BY since;

  • 配置wildfly释放连接:启用空闲超时
  • <timeout><idle-timeout-minutes>1</idle-timeout-minutes></timeout> 
    

    还要定义冲洗策略

    <flush-strategy>IdleConnections</flush-strategy> 
    

    要记录野蝇连接:http://www.javacodegeeks.com/2014/11/tomcat-wildfly-configuring-database-connectivity.html

    如果你能wildfly 9,你可以使用http://www.mastertheboss.com/jbossas/wildfly9/detecting-connection-leaks-in-wildfly-9

    0
    @Override 
    public boolean supportsAggressiveRelease() { 
        return true; // changing this true from false will fix the leak. 
    }