JDBC - 连接多个数据库
我正在研究一个需要连接N个数据库系统[N个范围在1到350之间的任何地方]的应用程序。JDBC - 连接多个数据库
的想法是 - 用户将数据库列表呈现,并会被要求选择任一或所有从列表中的数据库。
一旦数据库被选择,我需要连接到每个数据库并执行的存储过程。
我打算用普通的旧JDBC并获得他们每个人一个时间的[或由多个线程运行它们]连接并执行存储过程并关闭连接。
而这一切都应该发生在交易中。做这个的最好方式是什么?
如果不是JDBC ......任何其他有效的方式?
更新 -
的存储过程是实际参与运行一些SQL - 例如更新列的权限授予用户等
我想创建一个线程池有一个合理的最高金额线程,在10到20个线程之间,可以在Executors#newFixedThreadPool()
的帮助下调用单独的DB连接和SP执行任务,每个任务都使用ExecutorService#invokeAll()
作为Callable
。你想玩的线程数和个人资料,毕竟产生最好的表现。
每个Callable
实施应采取的连接细节和SP的名称作为构造函数的参数,这样就可以重新使用不同的数据库调用相同的实现。
更新:OK,这是一个web应用。你不想浪费线程。如果它应该被单个并发用户使用,那么你应该确保在请求结束时或者在会话的最高端线程池正确地为shutdown。但是,如果它应该被多个并发用户使用,那么你想在应用程序范围内共享线程池。同样在这里,你需要确保它在webapp关闭时正确关闭。 ServletContextListener
在这里很有用。
这听起来像是一团糟,但这是你的问题。
您需要每个数据库一个连接池。我不会建议您尝试自己处理连接生命周期。让应用服务器为你做。
如果您希望一组数据库参与一个大事务,那么您必须使用它们的所有的JDBC XA驱动程序。您还需要JTA交易管理器来为您监督交易。
的存储过程中不能包含任何逻辑来处理交易;你必须让JTA去做。
你不说什么存储过程正在做什么。如果它不需要返回任何东西,另一种设计可能是JMS,一个队列和一个监听器池。如果我是你,我会担心线程。我会找到一种方法让容器为我做些复杂的事情。
我猜所有的数据库连接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;
}
只需在350个数据库的一个循环中执行此操作。如果需要清理代码,请从主数据库提取每个数据库的参数。 – Zon 2014-05-02 16:54:42
什么样的应用?桌面还是网页? – skaffman 2010-08-06 21:10:14
这是一个Web应用程序。 – jagamot 2010-08-06 21:17:42
我的理解是,你不需要在一次交易中做到这一点,这是真的吗?除此之外还需要考虑更多。 – BalusC 2010-08-06 21:55:49