2010-08-06 50 views
9

Tôi đang làm việc trên một ứng dụng mà tôi cần kết nối N số hệ thống cơ sở dữ liệu [N dao động từ 1 đến 350].JDBC - Kết nối nhiều cơ sở dữ liệu

Ý tưởng là - người dùng sẽ được trình bày với danh sách cơ sở dữ liệu và sẽ được yêu cầu chọn bất kỳ hoặc tất cả cơ sở dữ liệu từ danh sách.

Khi cơ sở dữ liệu được chọn, tôi cần kết nối với từng cơ sở dữ liệu và thực hiện một thủ tục đã lưu.

Tôi định sử dụng JDBC cũ và nhận kết nối cho mỗi lần một hoặc [chạy chúng trong nhiều luồng] và thực hiện quy trình lưu trữ và đóng kết nối.

Và tất cả điều này sẽ xảy ra trong giao dịch. Cách tốt nhất để làm việc này là gì?

Nếu không JDBC ... bất kỳ cách hiệu quả nào khác?

Update -

Các thủ tục lưu trữ được thực sự tham gia vào hoạt động một số sql - ví dụ cập nhật một cột, cấp phép cho một người sử dụng, vv

+1

Những loại ứng dụng? Máy tính để bàn hoặc web? – skaffman

+0

Đây là một ứng dụng web. – jagamot

+0

Sự hiểu biết của tôi là bạn không cần phải làm điều này trong một giao dịch duy nhất, điều này có đúng không? Khác nhiều hơn nữa cần phải được đưa vào tài khoản. – BalusC

Trả lời

3

Tôi muốn tạo ra một threadpool với một số tiền tối đa hợp lý chủ đề, giữa mười và hai mươi chủ đề có thể, với sự giúp đỡ của Executors#newFixedThreadPool() và gọi DB riêng biệt kết nối và SP thực thi nhiệm vụ mỗi một Callable sử dụng ExecutorService#invokeAll(). Bạn muốn chơi với threadcount và hồ sơ mà mang lại hiệu suất tốt nhất sau khi tất cả.

Mỗi lần triển khai Callable sẽ lấy chi tiết kết nối và tên SP làm đối số hàm tạo để bạn có thể sử dụng lại cùng một triển khai cho các cuộc gọi DB khác nhau.


Cập nhật: OK, đây là ứng dụng web. Bạn không muốn lãng phí chủ đề. Nếu nó được cho là được sử dụng bởi một người dùng đồng thời duy nhất, thì bạn nên thực sự đảm bảo rằng threadpool là đúng shutdown khi kết thúc yêu cầu hoặc ở cuối phiên cao nhất. Nhưng nếu nó được cho là được sử dụng bởi nhiều người dùng đồng thời, thì bạn muốn chia sẻ threadpool trong phạm vi ứng dụng. Ngoài ra ở đây, bạn cần phải đảm bảo rằng nó được tắt đúng cách khi webapp tắt. ServletContextListener hữu ích ở đây.

0

Điều này nghe có vẻ như là một mớ hỗn độn lớn, nhưng đó là vấn đề của bạn.

Bạn cần một hồ bơi kết nối cho mỗi cơ sở dữ liệu. Tôi sẽ không khuyên bạn cố gắng tự xử lý vòng đời kết nối. Hãy để máy chủ ứng dụng làm điều đó cho bạn.

Nếu bạn muốn một nhóm cơ sở dữ liệu tham gia vào một giao dịch lớn, bạn sẽ phải sử dụng trình điều khiển JDBC XA cho tất cả trong số đó. Bạn cũng sẽ cần một người quản lý giao dịch JTA để giám sát giao dịch cho bạn.

Quy trình được lưu trữ không được chứa bất kỳ logic nào để xử lý giao dịch; bạn phải để JTA làm điều đó.

Bạn không nói quy trình lưu trữ đang làm gì. Nếu nó không cần phải trả lại bất cứ điều gì, một thiết kế thay thế có thể là JMS, một hàng đợi và một nhóm người nghe. Tôi sẽ lo lắng về luồng nếu tôi là bạn. Tôi sẽ tìm cách để cho các container làm những thứ phức tạp cho meif tôi có thể.

+0

Tôi đoán tất cả các kết nối cơ sở dữ liệu url được duy trì trong một cơ sở dữ liệu trung tâm. Tôi tin rằng chúng tôi không muốn tạo nguồn dữ liệu trong máy chủ ứng dụng [như đã đề cập, tôi có khoảng 1 - 350 nguồn dữ liệu] ..... trong trường hợp này, tôi đoán tôi cần xử lý vòng đời kết nối đúng không? – jagamot

1

Như duffymo đã nêu trong nhận xét của mình, bạn sẽ chỉ có thể thực hiện các giao dịch trên nhiều cơ sở dữ liệu nếu bạn có một điều phối viên giao dịch và hai giai đoạn cam kết.

Đối với điều này, bạn sẽ cần một ngăn xếp J2EE sẽ xử lý JTA. Nếu bạn đang chạy trong Tomcat hoặc vùng chứa khác không có JTA, có một số tùy chọn bạn có thể tải xuống và cài đặt.

Tất nhiên bạn sẽ cần phải để cho vùng chứa, không phải cơ sở dữ liệu/thủ tục lưu trữ xử lý các cam kết giao dịch và rollbacks.

2

Nếu bạn có thể sử dụng hai kết nối, hãy sử dụng hồ bơi kết nối c3p0 để quản lý chúng. Để kết nối hai cơ sở dữ liệu Tôi tuyên bố:

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

Sau đó, hai phương pháp tương tự:

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

Chỉ cần làm điều đó trong một chu kỳ cho 350 cơ sở dữ liệu của bạn. Trích xuất các tham số cho từng cơ sở dữ liệu từ cơ sở dữ liệu chính của bạn nếu cần để dọn sạch mã. – Zon

Các vấn đề liên quan