我在多租户环境中工作,可以使用webapplication(rest)前端从大约10个不同的数据源(和实体管理器)访问数据。
要使用的实体管理器取决于其余api中的URL参数,例如。 API /命令/ 1 / 1000003。
我需要使用entitymanager" 1"获取数据。目前我正在使用存储库层中的一个方法调用setDistrict(1),然后创建一个hibernate会话并通过hibernate Criteria创建一个查询。
一切正常,但我担心这个方法需要同步以避免从错误的实体管理器获取数据。 当我同步存储库方法时,我担心性能会很糟糕。
实施此多租户访问的好策略是什么,因此性能良好,并且在重负载下也会返回正确的数据?
感谢您的建议。
答案 0 :(得分:1)
Hibernate的SessionFactory允许使用tenancy behavior:
SCHEMA 与单独的架构方法相关联。尝试在没有租户标识符的情况下打开会话是错误的 这个策略。另外,一个 org.hibernate.service.jdbc.connections.spi.MultiTenantConnectionProvider 必须指明。
DATABASE 与单独的数据库方法相关联。尝试在没有租户标识符的情况下打开会话是错误的 使用这种策略。另外,一个 org.hibernate.service.jdbc.connections.spi.MultiTenantConnectionProvider 必须指明。
DISCRIMINATOR 与分区(鉴别器)方法相关联。尝试在没有租户的情况下打开会话是错误的 使用此策略的标识符。该战略尚未实施 在Hibernate中从4.0和4.1开始。它的支持计划为5.0。
在您的情况下,我认为您需要 SCHEMA 或 DATABASE ,并且必须实施 MultiTenantConnectionProvider (source)。
/**
* Simplisitc implementation for illustration purposes supporting 2 hard coded providers (pools) and leveraging
* the support class {@link org.hibernate.service.jdbc.connections.spi.AbstractMultiTenantConnectionProvider}
*/
public class MultiTenantConnectionProviderImpl extends AbstractMultiTenantConnectionProvider {
private final ConnectionProvider acmeProvider = ConnectionProviderUtils.buildConnectionProvider( "acme" );
private final ConnectionProvider jbossProvider = ConnectionProviderUtils.buildConnectionProvider( "jboss" );
@Override
protected ConnectionProvider getAnyConnectionProvider() {
return acmeProvider;
}
@Override
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
if ( "acme".equals( tenantIdentifier ) ) {
return acmeProvider;
}
else if ( "jboss".equals( tenantIdentifier ) ) {
return jbossProvider;
}
throw new HibernateException( "Unknown tenant identifier" );
}
}
有关详细信息,请参阅链接文档。