2015-04-14 50 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. 
    }