gpt4 book ai didi

hibernate - 我可以使用 Spring/Hibernate/c3p0 为多个数据库使用一个池数据源吗?

转载 作者:行者123 更新时间:2023-12-04 21:02:39 24 4
gpt4 key购买 nike

我们的应用程序使用 Spring/Hibernate 进行数据库访问。我们使用多个 hibernate session 工厂( hibernate3.LocalSessionFactoryBean ),因为数据位于多个单独的数据库中。每个 session 工厂都使用 c3p0 ( c3p0.ComboPooledDataSource ) 配置了一个池数据源。

碰巧的是,数据库都驻留在同一个数据库服务器上。我们的问题是我们最终得到了许多数据库连接池,它们都连接到同一台服务器上。有没有办法共享一个池数据源以访问同一台服务器上的多个数据库?是否可以配置 jdbcUrl在 session 工厂级别,而不是在数据源级别?

或者这在实践中不是一个真正的问题?配置多个数据库连接池是否完全可以?

最佳答案

一个连接连接到一个数据库。

如果您有 2 个数据库 DB1 和 DB2,并且想要一个连接池,那么您需要为这两个数据库准备好连接。

如果实际上每个池有 1 个连接,C1 和 C2(我知道你有更多,但它是一样的......)
当然可以将这两个连接放在同一个连接池中。
然后您将拥有一个带有 C1 和 C2 的连接池。
您对连接池有什么期望?对我来说 -> 能够为您提供可以直接使用的随机已经准备好的连接,而无需创建新连接的开销。

现在你猜怎么着,如果你的唯一池中有 C1 和 C2,你根本无法获得“随机”连接,因为它们不属于同一个数据库......因此你将有检查连接返回指向预期数据库的点,否则您将有 50% 的机会在 DB2 上执行请求 R1。

所以是的,这是可能的,您可以简单地实现自己的连接池,该连接池仅使用 2 个子连接池 CP1 和 CP2,并且将随机使用这些子连接池之一中的 getConnection,但您必须检查之后您使用正确的连接池,因此您最好将 2 个不同的连接池分开。

我不知道你为什么只想要一个连接池。也许您希望能够告诉您的应用程序“所有连接池都有 100 个连接”,并且您希望您的应用程序在您拥有的每个连接池中自动设置优化的连接数?对我来说似乎可能,但我不知道是否已经存在通用实现,也许您可​​以做一个连接池包装器,它将在所有现有池之间共享使用的平均连接百分比,然后调整池大小或类似的东西...

对我来说,在您的应用程序中有多个连接池是完全可以的。
除了在同一个应用程序中使用 2 个不同的数据库(Oracle + MongoDB 或类似的东西)完全可以,在同一台服务器上使用 2 个使用 2 个 Oracle 数据库模式的连接池也是完全可以的,即使两个数据库都有完全相同的表。

您应该查看具有多个客户(通常为 B2B)的 SaaS 应用程序的 Multi-Tenancy 策略:
- 一种是为每个客户拥有一个数据库,并且每个表都有一个“customer_id”列。维护起来更容易,但表上有更多行(但显然你索引了那个 customer_id 列)
- 另一种可能是您所做的:每个客户有一个数据库/数据源/连接池/ session 工厂,并且每个数据库都将具有相同的表。最终,您将拥有一些机制,例如“自定义的主 sessionfactory”,它将使用存储 customerId 的 ThreadLocal(由某些凭据过滤器设置?)来选择适当的子 sessionfactory。

以下面的文章为例(有很多关于该主题的文章):
http://relation.to/Bloggers/MultitenancyInHibernate

public class MyTenantAwareConnectionProvider implements ConnectionProvider {
public static final String BASE_JNDI_NAME_PARAM = "MyTenantAwareConnectionProvider.baseJndiName";

private String baseJndiName;

public void configure(Properties props) {
baseJndiName = props.getProperty( BASE_JNDI_NAME_PARAM );
}

public Connection getConnection() throws SQLException {
final String tenantId = TenantContext.getTenantId()
final String tenantDataSourceName = baseJndiName + '/' + tenantId;
DataSource tenantDataSource = JndiHelper.lookupDataSource( tenantDataSourceName );
return tenantDataSource.getConnection();
}

public void closeConnection(Connection conn) throws SQLException {
conn.close();
}

public boolean supportsAggressiveRelease() {
// so long as the tenant identifier remains available in TL throughout, we can
return true;
}

public close() {
// currently nothing to do here
}
}

这几乎就是我告诉你的,除了这里有一个动态连接提供者而不是动态 session 提供者。
(这里的租户 = 以我为例的客户)

您可以注意到本示例中没有连接池,但您确实可以实现自己的 PooledMyTenantAwareConnectionProvider ;)

祝你好运。

关于hibernate - 我可以使用 Spring/Hibernate/c3p0 为多个数据库使用一个池数据源吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8520255/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com