JDBC - 连接多个数据库

问题描述:

我正在研究一个需要连接N个数据库系统[N个范围在1到350之间的任何地方]的应用程序。JDBC - 连接多个数据库

的想法是 - 用户将数据库列表呈现,并会被要求选择任一或所有从列表中的数据库。

一旦数据库被选择,我需要连接到每个数据库并执行的存储过程。

我打算用普通的旧JDBC并获得他们每个人一个时间的[或由多个线程运行它们]连接并执行存储过程并关闭连接。

而这一切都应该发生在交易中。做这个的最好方式是什么?

如果不是JDBC ......任何其他有效的方式?

更新 -

的存储过程是实际参与运行一些SQL - 例如更新列的权限授予用户等

+1

什么样的应用?桌面还是网页? – skaffman 2010-08-06 21:10:14

+0

这是一个Web应用程序。 – jagamot 2010-08-06 21:17:42

+0

我的理解是,你不需要在一次交易中做到这一点,这是真的吗?除此之外还需要考虑更多。 – BalusC 2010-08-06 21:55:49

我想创建一个线程池有一个合理的最高金额线程,在10到20个线程之间,可以在Executors#newFixedThreadPool()的帮助下调用单独的DB连接和SP执行任务,每个任务都使用ExecutorService#invokeAll()作为Callable。你想玩的线程数和个人资料,毕竟产生最好的表现。

每个Callable实施应采取的连接细节和SP的名称作为构造函数的参数,这样就可以重新使用不同的数据库调用相同的实现。


更新:OK,这是一个web应用。你不想浪费线程。如果它应该被单个并发用户使用,那么你应该确保在请求结束时或者在会话的最高端线程池正确地为shutdown。但是,如果它应该被多个并发用户使用,那么你想在应用程序范围内共享线程池。同样在这里,你需要确保它在webapp关闭时正确关闭。 ServletContextListener在这里很有用。

这听起来像是一团糟,但这是你的问题。

您需要每个数据库一个连接池。我不会建议您尝试自己处理连接生命周期。让应用服务器为你做。

如果您希望一组数据库参与一个大事务,那么您必须使用它们的所有的JDBC XA驱动程序。您还需要JTA交易管理器来为您监督交易。

的存储过程中不能包含任何逻辑来处理交易;你必须让JTA去做。

你不说什么存储过程正在做什么。如果它不需要返回任何东西,另一种设计可能是JMS,一个队列和一个监听器池。如果我是你,我会担心线程。我会找到一种方法让容器为我做些复杂的事情。

+0

我猜所有的数据库连接URL都保存在*数据库中。我相信我们不想在应用程序服务器中创建数据源[如前所述,我有大约1 - 350个数据源] .....在这种情况下,我想我需要自己处理连接生命周期吗? – jagamot 2010-08-06 21:57:02

正如duffymo在他的评论中所指出的那样,如果你有一个事务协调器和两个阶段提交,你将只能在多个数据库上执行事务。

为此,您将需要一个将处理JTA的J2EE堆栈。如果您在Tomcat或另一个没有JTA的容器中运行,则可以下载和安装多个选项。

当然,您需要让容器而不是数据库/存储过程处理事务提交和回滚。

如果您可以使用两个连接,请使用连接池c3p0来管理它们。要连接两个数据库,我宣布:

public Connection connection1; 
public Connection connection2; 
DataSource dataSource1; 
DataSource dataSource2; 

然后两个类似的方法:

public Connection dbConnect1() throws SQLException { 
    ComboPooledDataSource cpds = new ComboPooledDataSource(); 
    try { 
     cpds.setDriverClass("com.mysql.jdbc.Driver"); 
    } catch (PropertyVetoException e) { 
    } 
    cpds.setJdbcUrl("jdbc:mysql://localhost:3306/myDatabase1?autoReconnect=true"); 
    cpds.setUser("myMYSQLServerLogin"); 
    cpds.setPassword("myMYSQLServerPassword"); 
    cpds.setMinPoolSize(5); 
    cpds.setAcquireIncrement(5); 
    cpds.setMaxPoolSize(20); 
    cpds.setMaxIdleTime(60); 
    cpds.setMaxStatements(100); 
    cpds.setPreferredTestQuery("SELECT 1"); 
    cpds.setIdleConnectionTestPeriod(60); 
    dataSource1 = cpds; 
    connection1 = dataSource1.getConnection(); 
    return connection1; 
} 

public Connection dbConnect2() throws SQLException { 
    ComboPooledDataSource cpds = new ComboPooledDataSource(); 
    try { 
     cpds.setDriverClass("com.mysql.jdbc.Driver"); 
    } catch (PropertyVetoException e) { 
    } 
    cpds.setJdbcUrl("jdbc:mysql://localhost:3306/myDatabase2?autoReconnect=true"); 
    cpds.setUser("myMYSQLServerLogin"); 
    cpds.setPassword("myMYSQLServerPassword"); 
    cpds.setMinPoolSize(5); 
    cpds.setAcquireIncrement(5); 
    cpds.setMaxPoolSize(20); 
    cpds.setMaxIdleTime(60); 
    cpds.setMaxStatements(100); 
    cpds.setPreferredTestQuery("SELECT 1"); 
    cpds.setIdleConnectionTestPeriod(60); 
    dataSource2 = cpds; 
    connection2 = dataSource2.getConnection(); 
    return connection2; 
} 
+0

只需在350个数据库的一个循环中执行此操作。如果需要清理代码,请从主数据库提取每个数据库的参数。 – Zon 2014-05-02 16:54:42