Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以将一个池数据源用于Spring/Hibernate/c3p0的多个数据库吗?_Hibernate_Spring_Datasource_C3p0 - Fatal编程技术网

我可以将一个池数据源用于Spring/Hibernate/c3p0的多个数据库吗?

我可以将一个池数据源用于Spring/Hibernate/c3p0的多个数据库吗?,hibernate,spring,datasource,c3p0,Hibernate,Spring,Datasource,C3p0,我们的应用程序使用Spring/Hibernate进行数据库访问。我们使用多个hibernate会话工厂(hibernate3.LocalSessionFactoryBean),因为数据位于多个单独的数据库中。使用c3p0(c3p0.ComboPooledDataSource)为每个会话工厂配置一个池数据源 碰巧,所有数据库都驻留在同一个db服务器上。我们的问题是,我们最终得到了许多数据库连接池,它们都连接到同一台服务器。有没有办法共享一个池数据源以访问同一服务器上的多个数据库?是否可以在会话工

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

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


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

我认为你做不到。我想我不会那样做。要么将它们视为单独的数据库,要么将它们视为一个数据库

如果它们是独立的数据库,它们有不同的连接池,需要由JTA管理,或者您需要为这些数据库之间的事务失败设计整个系统


如果他们被视为一体;您可以(如果您使用的是Oracle)创建一个连接池,然后使用alias和grants启用该连接以写入其他两个数据库。

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

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

如果实际上每个池有一个连接,C1和C2(我知道你有更多连接,但都是一样的…) 当然,可以将这两个连接放在同一个连接池中。 然后您将拥有一个连接池,其中包含C1和C2。 您对您的连接池有什么期望?对于我->能够给你随机的已经准备好的连接,你可以直接使用,而不需要创建新连接的开销

现在猜猜看,如果您的唯一池中同时有C1和C2,您就无法获得“随机”连接,因为它们不属于同一个数据库。。。因此,您将有检查连接是否返回指向预期数据库的开销,或者有50%的机会在DB2上执行请求R1

因此,是的,这是可能的,您可以简单地实现一个连接池,该连接池只使用两个子连接池CP1和CP2,并且将随机使用其中一个子连接池中的getConnection,但是,您必须在之后检查是否使用了正确的连接池,因此最好将两个不同的连接池分开

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


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


您应该了解具有多个客户(通常为B2B)的SaaS应用程序的多租户策略: -一种是每个客户有一个DB,每个表有一列“customer\u id”。维护起来更容易,但是表上有更多的行(但显然您索引了customer\u id列) -另一个可能是您要做的:每个客户有一个数据库/datasource/connectionpool/sessionfactory,每个数据库都有相同的表。最终,您将拥有一些mecanism,比如“定制的主sessionfactory”,它将使用ThreadLocal(由一些凭证过滤器设置?)来存储customerId以选择适当的子sessionfactory

以下面的文章为例(关于这个主题有很多):

除了这里有一个动态连接提供程序而不是一个动态会话提供程序之外,这几乎和我告诉你的一样。 (此处的租户=我的示例中的客户)

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

祝你好运

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