Управление пулами соединений в мультитенантном веб-приложении с помощью Spring, Hibernate и C3P0
я пытаюсь настроить мультитенантное веб-приложение с (в идеале) возможностью одновременно для подхода с разделением баз данных и схем. Хотя я'Я собираюсь начать со схемы разделения. Мы'в настоящее время используется:
Spring 4.0.0Hibernate 4.2.8Hibernate-c3p0 4.2.8 (который использует c3p0-0.9.2.1)и PostgreSQL 9.3 (я сомневаюсь, что это действительно имеет значение для общей архитектуры)В основном я следовалэта тема (из-за решения для@Transactional
). Но я'я как бы потерял в реализацииMultiTenantContextConnectionProvider
, Существует такжеэтот похожий вопрос спросил здесь о SO, но есть некоторые аспекты, которые я могут выяснить:
1) Что происходит с пулами соединений? Я имею в виду, это управляется Spring или Hibernate? Я думаю, сConnectionProviderBuilder
- или, как предложено, - в любой из его реализаций Hibernate - парень, который управляет этим.
2) Это хороший подход, что Spring не управляет пулами подключений? или даже возможно, что Spring справится с этим?
3) Является ли это правильным путем для будущей реализации разделения базы данных и схемы?
Любые комментарии или описания полностью приветствуются.
Приложение-context.xml
...
... other C3P0 related config
org.hibernate.dialect.PostgreSQLDialect
public
SCHEMA
com.webapp.persistence.utility.CurrentTenantContextIdentifierResolver
com.webapp.persistence.utility.MultiTenantContextConnectionProvider
...
CurrentTenantContextIdentifierResolver.java
public class CurrentTenantContextIdentifierResolver implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {
return CurrentTenantIdentifier; // e.g.: public, tid130, tid456, ...
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
MultiTenantContextConnectionProvider.java
public class MultiTenantContextConnectionProvider extends AbstractMultiTenantConnectionProvider {
// Do I need this and its configuratrion?
//private C3P0ConnectionProvider connectionProvider = null;
@Override
public ConnectionProvider getAnyConnectionProvider() {
// the main question is here.
}
@Override
public ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
// and of course here.
}
}
редактировать
относительноответ из @ ben75:
Это новая реализацияMultiTenantContextConnectionProvider
, Больше не распространяетсяAbstractMultiTenantConnectionProvider
, Скорее реализуетMultiTenantConnectionProvider
, чтобы иметь возможность вернуться[Connection][4]
вместо[ConnectionProvider][5]
public class MultiTenantContextConnectionProvider implements MultiTenantConnectionProvider, ServiceRegistryAwareService {
private DataSource lazyDatasource;;
@Override
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
Map lSettings = serviceRegistry.getService(ConfigurationService.class).getSettings();
lazyDatasource = (DataSource) lSettings.get( Environment.DATASOURCE );
}
@Override
public Connection getAnyConnection() throws SQLException {
return lazyDatasource.getConnection();
}
@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;
}
}