example java database jdbc

java - example - JDBC: conecta mĂșltiples bases de datos



java mysql connection (4)

Estoy trabajando en una aplicación en la que necesito conectar un número N de sistemas de bases de datos [N varía entre 1 y 350].

La idea es que al usuario se le presentará una lista de bases de datos y se le pedirá que seleccione cualquiera o todas las bases de datos de la lista.

Una vez que se seleccionan las bases de datos, necesito conectarme a cada una de las bases de datos y ejecutar un procedimiento almacenado.

Estoy planeando usar un viejo JDBC simple y obtener conexión para cada uno de ellos una vez [o ejecutarlos en varios hilos] y ejecutar el procedimiento de almacenamiento y cerrar la conexión.

Y todo esto debería suceder en una transacción. ¿Cuál es la mejor manera de hacer esto?

Si no es JDBC ... ¿alguna otra forma eficiente?

Actualización -

El procedimiento almacenado realmente está involucrado en la ejecución de algunos sql, por ejemplo, la actualización de una columna, la concesión de permisos para un usuario, etc.


Como Duffymo indicó en su comentario, solo podrá realizar transacciones en múltiples bases de datos si tiene un coordinador de transacciones y una confirmación de dos fases.

Para esto, necesitarás una pila J2EE que manejará JTA. Si está ejecutando en Tomcat u otro contenedor que no tiene JTA, hay varias opciones que puede descargar e instalar.

Por supuesto, deberá dejar que el Contenedor, y no la base de datos / procedimiento almacenado, maneje las confirmaciones y reversiones de transacción.


Esto suena como un gran desastre, pero es tu problema.

Necesita un grupo de conexiones por base de datos. No aconsejaría que intente manejar el ciclo de vida de la conexión usted mismo. Deje que el servidor de la aplicación haga eso por usted.

Si desea que un grupo de bases de datos participe de una gran transacción, deberá utilizar los controladores JDBC XA para todas ellas. También necesitará un administrador de transacciones JTA para supervisar la transacción por usted.

Los procedimientos almacenados no pueden contener ninguna lógica para manejar transacciones; tienes que dejar que JTA lo haga.

No dices lo que está haciendo el procedimiento almacenado. Si no necesita devolver nada, un diseño alternativo podría ser JMS, una cola y un grupo de escucha. Me preocuparía el enhebrarlo si fuera tú. Encontraría una manera de dejar que el contenedor haga esas cosas complicadas para mí si pudiera.


Si es aceptable que use dos conexiones, use el grupo de conexiones c3p0 para administrarlas. Para conectar dos bases de datos declaro:

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

Luego dos métodos similares:

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; }


Crearía un subproceso de subprocesos con una cantidad máxima razonable de subprocesos, entre diez y veinte subprocesos tal vez, con la ayuda de los Executors#newFixedThreadPool() e invocar las tareas de conexión de base de datos y de ejecución separadas cada una como un Callable utilizando ExecutorService#invokeAll() . Te gustaría jugar con la cuenta de hilos y el perfil que produce el mejor rendimiento después de todo.

Cada implementación Callable debe tomar los detalles de la conexión y el nombre del SP como argumento constructor para que pueda reutilizar la misma implementación para diferentes llamadas al DB.

Actualización : OK, es una aplicación web. No quieres perder los hilos. Si se supone que debe ser utilizado por un solo usuario concurrente, entonces realmente debe asegurarse de que el threadpool se cierre correctamente al final de la solicitud o en el extremo más alto de la sesión. Pero si se supone que es utilizado por múltiples usuarios simultáneos, entonces desea compartir el grupo de subprocesos en el ámbito de la aplicación. También aquí, debe asegurarse de que se cierre correctamente cuando la aplicación web se apaga. El ServletContextListener es útil aquí.