代码之家  ›  专栏  ›  技术社区  ›  jagamot

JDBC-连接多个数据库

  •  9
  • jagamot  · 技术社区  · 15 年前

    我正在开发一个应用程序,需要连接N个数据库系统(N个范围在1到350之间)。

    其思想是-用户将看到一个数据库列表,并将被要求从列表中选择任何或所有数据库。

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

    所有这些都应该在交易中发生。最好的方法是什么?

    如果不是JDBC…还有其他有效的方法吗?

    更新-

    4 回复  |  直到 15 年前
        1
  •  3
  •   BalusC    15 年前

    我将创建一个线程池,其中有一个合理的最大线程数,可能在10到20个线程之间,通过帮助 Executors#newFixedThreadPool() Callable 使用 ExecutorService#invokeAll()

    每个 可赎回 实现应将连接详细信息和SP name作为构造函数参数,以便可以对不同的DB调用重用同一实现。


    更新 :好的,这是一个web应用程序。你不想浪费时间。如果它应该由一个并发用户使用,那么您应该确保线程池是正确的 shutdown 在请求结束时或在会话的最高结束时。但是如果它应该由多个并发用户使用,那么您希望在应用程序范围内共享线程池。另外,在这里,您需要确保在webapp关闭时正确关闭它。这个 ServletContextListener 在这里很有用。

        2
  •  2
  •   Zon    12 年前

    如果您可以使用两个连接,请使用连接池 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;
    }
    
        3
  •  1
  •   Romain Hippeau    15 年前

    正如duffymo在他的评论中所指出的,只有在拥有事务协调器和两阶段提交的情况下,您才能跨多个数据库执行事务。

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

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

        4
  •  0
  •   duffymo    15 年前

    听起来很乱,但这是你的问题。

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

    全部的 其中之一。您还需要一个JTA事务管理器来监督您的事务。

    存储过程不能包含任何处理事务的逻辑;您必须让JTA来执行它。

    你不会说存储过程在做什么。如果不需要返回任何内容,另一种设计可能是JMS、队列和侦听器池。如果我是你,我会担心穿线的。我会想办法让集装箱帮我做那些复杂的事情。

        5
  •  0
  •   Sandeep Sharma    6 年前
    public static Connection getconnection(String db,String host){
    try {
    Class.forName("com.mysql.jdbc.Driver");
    Connection con = DriverManager.getConnection("jdbc:mysql://"+**Pass Your Host Here 
    Like Localhost**+"/"+Pass Your DB Name** +"?useUnicode=yes&characterEncoding=UTF- 
    8","root","root");
    return con;
    } catch (ClassNotFoundException | SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    return null;
    } 
    }