2010-08-06 2 views
9

Я работаю над приложением, где мне нужно подключить N количество систем баз данных [N охватывает любое место от 1 до 350].JDBC - Подключение нескольких баз данных

Идея заключается в том, что пользователю будет представлен список баз данных и будет предложено выбрать любую или все базы данных из списка.

После выбора баз данных мне необходимо подключиться к каждой базе данных и выполнить хранимую процедуру.

Я планирую использовать простой старый JDBC и получить соединение для каждого из них один раз [или запустив их в нескольких потоках] и выполнить процедуру хранения и закрыть соединение.

И все это должно произойти в транзакции. Каков наилучший способ сделать это?

Если нет JDBC ... любой другой эффективный способ?

Update -

Хранимая процедура на самом деле участвует в запуске некоторых SQL - например, обновление столбца, предоставить разрешение для пользователя и т.д.

+1

Какие приложения? Настольный или веб-сайт? – skaffman

+0

Это веб-приложение. – jagamot

+0

Я понимаю, что вам не нужно делать это за одну транзакцию, это правда? Еще многое нужно учитывать. – BalusC

ответ

3

Я бы создать ThreadPool с разумным максимальным количеством потоки, между десятью и двадцатью нитями, возможно, с помощью Executors#newFixedThreadPool() и вызывать отдельное соединение DB и выполнение SP-задач каждый как Callable с использованием ExecutorService#invokeAll(). Вы хотели бы сыграть с профилем threadcount и профилем, который в итоге обеспечит наилучшую производительность.

Каждая реализация Callable должна содержать сведения о соединении и имя SP в качестве аргумента конструктора, чтобы вы могли повторно использовать ту же реализацию для разных вызовов БД.


Update: Хорошо, это WebApplication. Вы не хотите тратить нитки. Если предполагается, что он будет использоваться одним одновременным пользователем, вы должны действительно убедиться, что threadpool правильно shutdown в конце запроса или в самом верхнем конце сеанса. Но если это предполагается использовать несколькими одновременными пользователями, то вы хотите разделить threadpool в области приложения. Также здесь вам нужно убедиться, что он корректно выключается, когда веб-камера отключается. Здесь полезен ServletContextListener.

0

Это звучит как большой беспорядок, но это ваша проблема.

Для каждой базы данных необходим один пул соединений. Я бы не советовал, чтобы вы сами пытались справиться с жизненным циклом соединения. Пусть сервер приложений сделает это за вас.

Если вы хотите, чтобы группа баз данных участвовала в одной крупной транзакции, вам придется использовать драйверы JDBC XA для всех из них. Вам также понадобится менеджер транзакций JTA для контроля за транзакцией для вас.

Хранимые процедуры не могут содержать никакой логики для обработки транзакций; вы должны позволить JTA сделать это.

Вы не говорите, что делает хранимая процедура. Если ему не нужно ничего возвращать, альтернативным дизайном может быть JMS, очередь и пул слушателей. Если бы я был вами, я бы беспокоился о том, чтобы нарезать резьбу. Я бы нашел способ позволить контейнеру сделать этот сложный материал для меня, как мог.

+0

Я предполагаю, что все ссылки на соединение с базой данных хранятся в центральной базе данных. Я считаю, что мы не хотим создавать источники данных на сервере приложений [как уже упоминалось, у меня около 1 - 350 источников данных] ..... в этом случае, я думаю, мне нужно правильно управлять жизненным циклом соединения? – jagamot

1

Как указано в его комментарии, вы можете выполнять транзакции только через несколько баз данных, если у вас есть координатор транзакции и двухфазный фиксатор.

Для этого вам понадобится стек J2EE, который будет обрабатывать JTA. Если вы работаете в Tomcat или другом контейнере, у которого нет JTA, есть несколько параметров, которые вы можете загрузить и установить.

Конечно, вам нужно будет разрешить Контейнеру, а не базе данных/хранимой процедуре обрабатывать транзакцию и откаты.

2

Если вам разрешено использовать два соединения, используйте пул соединений 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

Смежные вопросы