2017-12-31 162 views
1

내가로 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 
    } 
... 
} 

내 연결 풀 크기가, 지금은 유효하지 않은 tenantIdentifier 10 번 전달되는 경우, 10 10 응용 프로그램이 연결을 얻을 수 없으면 연결이 고갈됩니다.

시도한 던지는 Exception, HibernateException 시도했지만 도움이되지 않았습니다. default schema과의 연결을 사용하면 잘못된 결과가 가져옵니다. 연결 제한을 고갈하지 않기 위해이 시나리오를 getConnection()에 처리 할 수있는 방법이 있습니까?

+0

난 당신이 또한 무시 희망'''공공 무효 releaseConnection (문자열 tenantIdentifier, 연결 연결)'''여기 당신의 대답에 대한 – Barath

답변

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); 
     } 

     ... 
    } 

다음, 미세 조정 스프링 부팅에서 데이터 소스 구성 :

# 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 

참조 : 문제가 계속 지속 Working with datasources

경우, 등등 히카리와 같은 데이터 소스 연결 풀링 메커니즘 지원으로 진행

+0

감사를 conncection을 닫는. 사실 나는 당신이 언급 한 것처럼 HikariCP를 사용하고 releaseConnection에서 연결을 해제하고 있습니다. 이것은 작동하지 않았다. 이제 오류가 발생하는 동안 getConnection()에서 연결을 닫으려고했으나 – jaks

+0

괜찮 았지만 getConnection()에서 연결을 닫을 필요가 없습니다. 분명히 연결을 얻는 동안 예외가 발생하더라도 호출자는 releaseConnection 메소드를 호출합니다. 연결 인스턴스가 닫히도록하는 releaseConnection 메소드를 다시 확인하십시오. – Barath

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 
    }