2010-08-06 6 views
9

나는 N 개의 데이터베이스 시스템 [N 개의 범위 1 ~ 350 사이]을 연결해야하는 응용 프로그램에서 작업하고 있습니다.JDBC - 여러 데이터베이스 연결

아이디어는 다음과 같습니다. - 사용자에게 데이터베이스 목록이 표시되고 목록에서 일부 또는 모든 데이터베이스를 선택하라는 메시지가 표시됩니다.

일단 데이터베이스를 선택하면 각 데이터베이스에 연결하고 저장 프로 시저를 실행해야합니다.

평범한 JDBC를 사용하고 각 JDBC 드라이버를 한 번에 [또는 여러 스레드에서 실행하여] 연결을 얻고 저장소 프로 시저를 실행하고 연결을 닫을 계획입니다.

이 모든 것이 트랜잭션에서 발생해야합니다. 이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

JDBC가 아닌 경우 ... 다른 효율적인 방법은 무엇입니까?

업데이트 -

가 저장 프로 시저가 실제로 어떤 SQL을 실행에 관여

- 예를 들어 열을 업데이트, 사용자에 대한 권한을 부여 등

나는 합리적인 최대 금액으로 스레드를 만들 것
+1

어떤 종류의? 데스크톱 또는 웹? – skaffman

+0

웹 응용 프로그램입니다. – jagamot

+0

제 생각에는 단일 거래에서이 작업을 수행 할 필요가 없다는 것입니다. 사실입니까? 그 외에도 더 많은 것을 고려해야합니다. – BalusC

답변

3

쓰레드는 Executors#newFixedThreadPool()의 도움으로 10 개에서 20 개 사이의 쓰레드를 생성하고 각각 Callable으로 ExecutorService#invokeAll()을 사용하여 DB 연결 및 SP 실행 태스크를 호출하십시오. 결국 최고의 실적을내는 threadcount 및 프로필로 게임을하고 싶습니다.

Callable 구현은 다른 DB 호출에 대해 동일한 구현을 재사용 할 수 있도록 연결 세부 정보와 SP 이름을 생성자 인수로 사용해야합니다.


업데이트는 : OK, 그것은 웹 어플리케이션입니다. 스레드를 낭비하지 않으려 고합니다. 단일 동시 사용자가 사용해야하는 경우에는 요청이 끝나거나 세션의 가장 마지막에 스레드 풀이 올바르게 shutdown인지 확인해야합니다. 그러나 여러 동시 사용자가이를 사용해야하는 경우 응용 프로그램 범위에서 스레드 풀을 공유하려고합니다. 또한 여기에서는 웹 응용 프로그램이 종료 될 때 제대로 종료되었는지 확인해야합니다. 여기서 ServletContextListener이 유용합니다.

0

이것은 큰 혼란처럼 들리지만 문제입니다.

데이터베이스 당 하나의 연결 풀이 필요합니다. 연결 라이프 사이클을 직접 처리하도록 권하지 않습니다. 앱 서버가 대신 해줍니다.

데이터베이스 그룹을 하나의 큰 거래에 참여 시키려면 에 대한 JDBC XA 드라이버를 모두 개 사용해야합니다. 또한 트랜잭션을 감독하기 위해 JTA 트랜잭션 관리자가 필요합니다.

저장 프로 시저에는 트랜잭션을 처리 할 논리가 포함될 수 없습니다. 당신은 JTA가 그렇게하도록해야합니다.

저장 프로 시저가 수행중인 작업을 말하지 않습니다. 반환 할 필요가없는 경우 대체 설계는 JMS, 대기열 및 수신기 풀일 수 있습니다. 내가 너라면 스레딩에 대해 걱정할거야. 컨테이너가 내가 할 수있는 일을 위해 복잡한 것을 할 수있는 방법을 찾았습니다.

+0

나는 모든 데이터베이스 연결 URL이 중앙 데이터베이스에서 관리되고 있다고 생각한다. 나는 우리가 애플 리케이션 서버에 데이터 소스를 생성하고 싶지 않다고 믿는다. (내가 말했듯이 약 1 - 350 개의 데이터 소스를 가지고있다.) ..... 어떤 경우에는 연결 라이프 사이클을 직접 처리해야 할 필요가 있을까? – jagamot

1

duffymo가 그의 의견에서 지적한 것처럼, 트랜잭션 코디네이터와 2 단계 커밋이있는 경우에만 여러 데이터베이스에서 트랜잭션을 수행 할 수 있습니다.

이렇게하려면 JTA를 처리 할 J2EE 스택이 필요합니다. Tomcat 또는 JTA가없는 다른 컨테이너에서 실행중인 경우 다운로드하여 설치할 수있는 몇 가지 옵션이 있습니다.

물론 데이터베이스/저장 프로 시저가 트랜잭션 커밋과 롤백을 처리하는 것이 아니라 컨테이너를 보내야합니다.

2

2 개의 연결을 사용할 수 있으면 연결 풀 c3p0을 사용하여 연결을 관리하십시오. 두 개의 데이터베이스를 연결하려면 I 선언 :

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