我知道关于这种情况也有类似的问题,但是我发现它们都不符合我的情况,我希望有一个不会影响性能的解决方案。我必须与不同的数据库(所有postgresql)建立多个连接,问题是数据库可能很多,因为它们不断被创建。
目前我只有一个已知的数据库,用于存储来自其他数据库的连接字符串。这些数据库可以是1,2,5,10或N,棘手的部分是,从我的角度来看,我永远不会知道他们将会有多少以及他们的位置和凭据是什么(都存储在我的中央数据库中) 。该用例的工作方式是,为了在这些数据库之一上进行操作,我必须首先从中央数据库中获取所需数据库的位置,然后执行操作。
目前,我已经能够通过单一的SessionFactory执行操作,但即使是简单的选择/更新,操作也太慢了,我担心的是,当发出多个请求时,我们可能会从Hibernate获得内存异常。
关于这种情况的最佳方法的任何想法?
答案 0 :(得分:1)
我们有类似的事情: 1..N数据库作为不同的客户。每个客户都有相同的架构,因此我们只有1个实体管理器。 所以你需要通过spi 2实现类提供hibernete,并通过属性提供handen:
<强> hibernate.multi_tenant_connection_provider 强> 的 org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider 强>
和 的 hibernate.tenant_identifier_resolver 强> 的 org.hibernate.context.spi.CurrentTenantIdentifierResolver 强>
&#34; hibernate.multiTenancy&#34;,&#34; SCHEMA&#34;
以下是如何使用spring framework
执行此操作的示例 LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setJpaVendorAdapter(jpaVendorAdapter());
emf.setPersistenceUnitName("security");
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.cache.use_second_level_cache", "true");
hibernateProperties.put("hibernate.multiTenancy", "SCHEMA");
// do not load all metadata from standard db speadup startup
hibernateProperties.put("hibernate.temp.use_jdbc_metadata_defaults", "false");
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL9Dialect");
hibernateProperties.put("hibernate.multi_tenant_connection_provider", multiTenantConnectionProvider());
hibernateProperties.put("hibernate.tenant_identifier_resolver", currentTenantIdentifierResolver(tenant));
hibernateProperties.put("hibernate.show_sql", true);
emf.setJpaProperties(hibernateProperties);
emf.setJpaDialect(new HibernateJpaDialect());
LOG.info("LocalContainerEntityManagerFactoryBean bean created");
return emf;
答案 1 :(得分:0)
根据我的经验,我使用了来自单个数据库的许多模式。
Hibernate需要为每个单独的模式以及每个数据库创建许多EntityManagerFactory。
每个模式或您正在使用的每个数据库都需要一个EntityManagerFactory。
而且你知道EntityManagerFactory在资源和时间方面非常昂贵。
之后获得单个EntityManager非常便宜。
因此,在您的情况下,您必须创建一个N EntityManagerFactory,其中一个用于每个不同的数据库或来自相同数据库的不同模式。
由于创建EntityManagerFactory的成本很高,因此必须在必要时和必要时创建它们,并且您知道必须等待将近30秒或更长时间才能获得所有人。
为了避免内存不足异常,您可以尝试进行测试,以创建从1到N的最大EntityManagerFactory数,并查看您的资源是否可以支持此功能。
如果你看到当你到达一个X号码并且因为这总是系统崩溃而烦恼时,那么你可以将EntityManagerFactory的同时数限制为这个X限制数。
尝试让我知道您的结果,或者您是否需要一些代码示例
答案 2 :(得分:0)
我正以一种不同的方式思考这个问题。
根据我的理解
您的要求是从不同的数据库中获取数据 你在发展的时候不知道。
所以为什么你试图将所有这些负载放在hibernate上来管理与这么多数据库的连接。
你很清楚主数据库是什么。
让master数据库做其余事情。
您应该只与master数据库通信以及获取所有负担 其余数据库中的数据应保存在主数据库中。
为master数据库中的不同数据库创建DBLink。
并在master数据库中维护所需的元数据。
每当您需要从任何新添加的数据库中获取数据时, 刚刚从master数据库询问。
使用DBLinks可以解决的问题