4.1 The aim of the study
4.3.3 Time Three
Generalmente, en Java Database Connectivity (JDBC) las transacciones son locales. Esto significa que una sola conexión realiza todo el trabajo de la transacción y que la conexión sólo puede trabajar en una transacción a la vez. Cuando todo el trabajo para esa transacción ha finalizado o ha fallado, se llama al compromiso o a la retrotracción para convertir el trabajo en permanente y puede empezar una nueva transacción.
Existe un soporte avanzado para transacciones disponible en Java que proporciona funciones que van más allá de las transacciones locales. Este soporte se especifica plenamente en la especificación de la API de transacción Java (JTA) 1.0.1
.
La API de transacción Java (JTA) tiene soporte para transacciones complejas. También proporciona soporte para desasociar transacciones de objetos Connection. Al igual que JDBC se ha diseñado a partir de las especificaciones Object Database Connectivity (ODBC) y X/Open Call Level Interface (CLI), JTA se ha diseñado a partir de la especificación X/Open Extended Architecture (XA). JTA y JDBC funcionan conjuntamente para desasociar transacciones a partir de objetos Connection. El hecho de desasociar transacciones de objetos Connection permite que una sola conexión trabaje en varias transacciones simultáneamente. A la inversa, permite que varias conexiones trabajen en una sola transacción.
Nota: si tiene previsto trabajar con JTA, consulte la sección Iniciación a JDBC para obtener más información acerca de los archivos Java Archive (JAR) necesarios en la vía de acceso de clases de extensiones. Desea utilizar tanto el paquete opcional de JDBC 2.0 como los archivos JAR de JTA (JDK encuentra automáticamente estos archivos si ejecuta JDK 1.4). No se encuentran por omisión.
Transacciones con JTA: Cuando JTA y JDBC se utilizan conjuntamente, existen una serie de pasos entre ellos para realizar el trabajo transaccional. Se proporciona soporte para XA mediante la clase XADataSource. Esta clase contiene soporte para configurar la agrupación de conexiones exactamente de la misma forma que su superclase ConnectionPoolDataSource.
Con una instancia de XADataSource, puede recuperar un objeto XAConnection. El objeto XAConnection funciona como contenedor tanto para el objeto JDBC Connection como para un objeto XAResource. El objeto XAResource está diseñado para manejar el soporte transaccional XA. XAResource maneja las transacciones mediante objetos denominados ID de transacción (XID).
XID es una interfaz que debe implementar. Representa una correlación Java de la estructura XID del identificador de transacción X/Open. Este objeto contiene tres partes:
v Un ID formato de transacción global
v Una transacción global v Un calificador de rama
Consulte la especificación JTA para obtener detalles completos acerca de esta interfaz.
El Ejemplo: utilizar JTA para manejar una transacción muestra cómo utilizar JTA para manejar una transacción en una aplicación.
Utilizar el soporte de UDBXADataSource para agrupación y transacciones distribuidas: El soporte de API de transacción Java proporciona soporte directo para agrupación de conexiones.
UDBXADataSource es una ampliación de ConnectionPoolDataSource, que permite el acceso de las aplicaciones a objetos XAConnection agrupados. Puesto que UDBXADataSource es un
ConnectionPoolDataSource, la configuración y utilización de UDBXADataSource es la misma que la descrita en la sección Utilizar el soporte de DataSource para agrupación de objetos.
Propiedades de XADataSource: Además de las propiedades que proporciona
ConnectionPoolDataSource, la interfaz XADataSource proporciona las siguientes propiedades:
Método Set (tipo de datos)
Valores Descripción
setLockTimeout (int)
0 o cualquier valor positivo Cualquier valor positivo es un tiempo de espera de bloqueo válido (en segundos) a nivel de transacción.
Un tiempo de espera de bloqueo 0 significa que no se impone ningún valor de tiempo de espera de bloqueo a nivel de transacción, aunque puede imponerse uno a otros niveles (el trabajo o la tabla).
El valor por omisión es 0. setTransactionTimeout
(int)
0 o cualquier valor positivo Cualquier valor positivo es un tiempo de espera de transacción válido (en segundos).
Un tiempo de espera de transacción 0 significa que no se impone ningún tiempo de espera de transacción. Si la transacción permanece activa durante más tiempo del que indica el valor de tiempo de espera, se marca como de sólo retrotracción y los intentos subsiguientes de realizar trabajo en ella provocan una excepción.
El valor por omisión es 0.
ResultSets y transacciones: Además de demarcar el inicio y la finalización de una transacción, como se ha mostrado en el ejemplo anterior, las transacciones pueden suspenderse durante un tiempo y reanudarse más tarde. Esto proporciona diversos escenarios para los recursos de ResultSet creados durante una transacción.
Fin de transacción simple: Al finalizar una transacción, todos los ResultSets abiertos que se crearon bajo esa transacción se cierran automáticamente. Es aconsejable cerrar explícitamente los ResultSets cuando haya terminado de utilizarlos para garantizar el máximo de proceso paralelo. Sin embargo, se produce una excepción si se accede a cualquier ResultSet que estaba abierto durante una transacción después de efectuar la llamada a XAResource.end.
Consulte el Ejemplo: finalizar una transacción, que muestra este comportamiento.
Suspender y reanudar: Mientras una transacción está suspendida, el acceso a un ResultSet creado mientras la transacción estaba activa no está permitido y provoca una excepción. Sin embargo, una vez que la transacción se ha reanudado, el ResultSet está disponible de nuevo y permanece en el mismo estado en que estaba antes de que se suspendiera la transacción.
Efectuar ResultSets suspendidos: Mientras una transacción está suspendida, no puede accederse al ResultSet. Sin embargo, los objetos Statement pueden reprocesarse bajo otra transacción para realizar el trabajo. Debido a que los objetos JDBC Statement sólo pueden tener un ResultSet a la vez (excluyendo el soporte de JDBC 3.0 para varios ResultSets simultáneos de una llamada de procedimiento almacenado), el ResultSet de la transacción suspendida debe cerrarse para satisfacer la petición de la nueva
transacción. Esto es exactamente lo que ocurre.
Consulte el Ejemplo: ResultSets suspendidos, que muestra este comportamiento.
Nota: Aunque JDBC 3.0 permite que un objeto Statement tenga varios ResultSets abiertos
simultáneamente para una llamada de procedimiento almacenado, éstos se tratan como una sola unidad y todos ellos se cierran si el objeto Statement se reprocesa bajo una transacción nueva. Actualmente, no es posible tener ResultSets procedentes de dos transacciones activas simultáneamente para una sola sentencia.
Multiplexado: La API JTA está diseñada para desasociar transacciones de conexiones JDBC. Esta API permite que varias conexiones trabajen en una sola transacción o que una sola conexión trabaje en varias transacciones simultáneamente. Esto se denomina multiplexado, que permite realizar muchas tareas complejas que no pueden realizarse sólo con JDBC.
Este ejemplo muestra varias conexiones que trabajan en una sola transacción.
Este ejemplo muestra una sola conexión con varias transacciones que tienen lugar a la vez.
Para obtener más información acerca de la utilización de JTA, consulte la especificación JTA. La especificación JDBC 3.0 también contiene información acerca de cómo estas dos tecnologías funcionan conjuntamente para dar soporte a las transacciones distribuidas.
Compromiso de dos fases y anotación de transacciones: Las API JTA externalizan las
responsabilidades del protocolo de compromiso de dos fases distribuido completamente en la aplicación. Como se ha mostrado en los ejemplos, al utilizar JTA y JDBC para acceder a una base de datos bajo una transacción JTA, la aplicación utiliza los métodos XAResource.prepare() y XAResource.commit() o sólo el método XAResource.commit() para comprometer los cambios.
Además, al acceder a varias bases de datos distintas utilizando una sola transacción, es responsabilidad de la aplicación garantizar que se realicen el protocolo de compromiso de dos fases y las anotaciones asociadas necesarias para la atomicidad de la transacción en esas bases de datos. Generalmente, el proceso de compromiso de dos fases en varias bases de datos (es decir, XAResources) y sus
anotaciones se realizan bajo el control de un servidor de aplicaciones o de un supervisor de transacciones para que la propia aplicación no tenga que preocuparse de estas cuestiones.
Por ejemplo, la aplicación puede llamar a algún método commit() o efectuar la devolución desde su proceso sin errores. El servidor de aplicaciones o supervisor de transacciones subyacente empezará entonces a procesar cada una de las bases de datos (XAResource) que ha participado en la única transacción distribuida.
El servidor de aplicaciones utilizará anotaciones extensivas durante el proceso de compromiso de dos fases. Llamará al método XAResource.prepare() para cada base de datos participante (XAResource), seguido de una llamada al método XAResource.commit() para cada base de datos participante (XAResource).
Si se produce una anomalía durante este proceso, las anotaciones del supervisor de transacciones del servidor de aplicaciones permiten que el propio servidor de aplicaciones utilice subsiguientemente las API de JTA para recuperar la transacción distribuida. Esta recuperación, bajo el control del servidor de
estado conocido en cada base de datos participante (XAResource). Con ello garantiza un estado conocido de toda la transacción distribuida en todas las bases de datos participantes.
Ejemplo: utilizar JTA para manejar una transacción:
Este es un ejemplo de utilización de la API de transacción Java (JTA) para manejar una transacción en una aplicación.
Ejemplo: utilizar JTA para manejar una transacción
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
import java.sql.*; import javax.sql.*; import java.util.*; import javax.transaction.*; import javax.transaction.xa.*; import com.ibm.db2.jdbc.app.*; public class JTACommit {
public static void main(java.lang.String[] args) { JTACommit test = new JTACommit();
test.setup(); test.run(); }
/**
* Manejar la ejecución de limpieza anterior para que esta prueba pueda volver a empezar. */
public void setup() { Connection c = null; Statement s = null; try { Class.forName(″com.ibm.db2.jdbc.app.DB2Driver″); c = DriverManager.getConnection(″jdbc:db2:*local″); s = c.createStatement(); try {
s.executeUpdate(″DROP TABLE CUJOSQL.JTATABLE″); } catch (SQLException e) {
// Ignorar... no existe }
s.executeUpdate(″CREATE TABLE CUJOSQL.JTATABLE (COL1 CHAR (50))″); s.close();
} finally {
c.close(); }
} } /**
* Esta prueba utiliza el soporte JTA para manejar transacciones. */
public void run() { Connection c = null;
try {
Context ctx = new InitialContext();
// Presuponer que el origen de datos se apoya en un UDBXADataSource. UDBXADataSource ds = (UDBXADataSource) ctx.lookup(″XADataSource″); // Desde el DataSource, obtener un objeto XAConnection que
// contiene un XAResource y un objeto Connection. XAConnection xaConn = ds.getXAConnection(); XAResource xaRes = xaConn.getXAResource(); Connection c = xaConn.getConnection();
// Para transacciones XA, es necesario un identificador de transacción. // No se incluye una implementación de la interfaz XID con el
// controlador JDBC. Consulte “Transacciones con JTA” en la página 111 // para obtener una descripción de esta interfaz para crear una clase // para ella.
Xid xid = new XidImpl();
// La conexión de XAResource puede utilizarse como // cualquier otra conexión JDBC.
Statement stmt = c.createStatement();
// Debe informarse al recurso XA antes de iniciar cualquier // trabajo transaccional.
xaRes.start(xid, XAResource.TMNOFLAGS); // Se realiza el trabajo JDBC estándar.
int count = stmt.executeUpdate(″INSERT INTO CUJOSQL.JTATABLE VALUES(’JTA is pretty fun.’)″); // Cuando el trabajo de transacción ha terminado, debe informarse
// de nuevo al recurso XA.
xaRes.end(xid, XAResource.TMSUCCESS);
// La transacción representada por el ID de transacción se prepara // para el compromiso.
int rc = xaRes.prepare(xid);
// La transacción se compromete mediante el XAResource. // No se utiliza el objeto JDBC Connection para comprometer // la transacción al utilizar JTA.
} catch (Exception e) {
System.out.println(″Algo ha fallado.″); e.printStackTrace(); } finally { try { if (c != null) c.close(); } catch (SQLException e) {
System.out.println(″Nota: Excepción de limpieza.″); e.printStackTrace();
} } } }
Ejemplo: varias conexiones que funcionan en una transacción:
Este es un ejemplo de utilización de varias conexiones que trabajan en una sola transacción.
Ejemplo: Varias conexiones que trabajan en una transacción
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
import java.sql.*; import javax.sql.*; import java.util.*; import javax.transaction.*; import javax.transaction.xa.*; import com.ibm.db2.jdbc.app.*; public class JTAMultiConn {
public static void main(java.lang.String[] args) { JTAMultiConn test = new JTAMultiConn();
test.setup(); test.run(); }
/**
* Manejar la ejecución de limpieza anterior para que esta prueba pueda volver a empezar. */
public void setup() { Connection c = null; Statement s = null; try { Class.forName("com.ibm.db2.jdbc.app.DB2Driver"); c = DriverManager.getConnection("jdbc:db2:*local"); s = c.createStatement(); try {
s.executeUpdate("DROP TABLE CUJOSQL.JTATABLE"); }
catch (SQLException e) { // Ignorar... no existe }
s.executeUpdate("CREATE TABLE CUJOSQL.JTATABLE (COL1 CHAR (50))"); s.close(); } finally { if (c != null) { c.close();
} } } /**
* Esta prueba utiliza el soporte JTA para manejar transacciones. */
public void run() { Connection c1 = null; Connection c2 = null; Connection c3 = null;
try {
Context ctx = new InitialContext();
// Presuponer que el origen de datos se apoya en un UDBXADataSource. UDBXADataSource ds = (UDBXADataSource)
ctx.lookup("XADataSource");
// Desde el DataSource, obtener algunos objetos XAConnection que // contienen un XAResource y un objeto Connection.
XAConnection xaConn1 = ds.getXAConnection(); XAConnection xaConn2 = ds.getXAConnection(); XAConnection xaConn3 = ds.getXAConnection(); XAResource xaRes1 = xaConn1.getXAResource(); XAResource xaRes2 = xaConn2.getXAResource(); XAResource xaRes3 = xaConn3.getXAResource(); c1 = xaConn1.getConnection(); c2 = xaConn2.getConnection(); c3 = xaConn3.getConnection(); Statement stmt1 = c1.createStatement(); Statement stmt2 = c2.createStatement(); Statement stmt3 = c3.createStatement();
// Para transacciones XA, es necesario un identificador de transacción. // El soporte para crear XIDs se deja de nuevo al
// programa de aplicación. Xid xid = JDXATest.xidFactory();
// Realizar algún trabajo transaccional bajo cada una de las tres // conexiones que se han creado.
xaRes1.start(xid, XAResource.TMNOFLAGS);
int count1 = stmt1.executeUpdate("INSERT INTO " + tableName + "VALUES(’Value 1-A’)"); xaRes1.end(xid, XAResource.TMNOFLAGS);
xaRes2.start(xid, XAResource.TMJOIN);
int count2 = stmt2.executeUpdate("INSERT INTO " + tableName + "VALUES(’Value 1-B’)"); xaRes2.end(xid, XAResource.TMNOFLAGS);
xaRes3.start(xid, XAResource.TMJOIN);
int count3 = stmt3.executeUpdate("INSERT INTO " + tableName + "VALUES(’Value 1-C’)"); xaRes3.end(xid, XAResource.TMSUCCESS);
// Al terminar, comprometer la transacción como una sola unidad. // Es necesario prepare() y commit() o commit() de 1 fase para
// cada base de datos independiente (XAResource) que ha participado en la // transacción. Dado que los recursos a los que se ha accedido
// (xaRes1, xaRes2 y xaRes3)
// hacen todos referencia a la misma base de datos, sólo es necesaria una // prepare o commit. int rc = xaRes.prepare(xid); xaRes.commit(xid, false); } catch (Exception e) { System.out.println("Algo ha fallado."); e.printStackTrace(); } finally { try { if (c1 != null) { c1.close(); } } catch (SQLException e) {
System.out.println("Nota: Excepción de limpieza " + e.getMessage()); } try { if (c2 != null) { c2.close(); } } catch (SQLException e) {
System.out.println("Nota: Excepción de limpieza " + e.getMessage()); } try { if (c3 != null) { c3.close(); } } catch (SQLException e) {
System.out.println("Nota: Excepción de limpieza " + e.getMessage());
} } } }
Ejemplo: utilizar una conexión con varias transacciones:
Este es un ejemplo de utilización de una sola conexión con varias transacciones.
Ejemplo: utilizar una conexión con varias transacciones
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
import java.sql.*; import javax.sql.*; import java.util.*; import javax.transaction.*; import javax.transaction.xa.*; import com.ibm.db2.jdbc.app.*; public class JTAMultiTx {
public static void main(java.lang.String[] args) { JTAMultiTx test = new JTAMultiTx();
test.setup(); test.run(); }
/**
* Manejar la ejecución de limpieza anterior para que esta prueba pueda volver a empezar. */
public void setup() { Connection c = null; Statement s = null;
try {
Class.forName("com.ibm.db2.jdbc.app.DB2Driver");
s = c.createStatement(); try {
s.executeUpdate("DROP TABLE CUJOSQL.JTATABLE"); } catch (SQLException e) {
// Ignorar... no existe }
s.executeUpdate("CREATE TABLE CUJOSQL.JTATABLE (COL1 CHAR (50))"); s.close(); } finally { if (c != null) { c.close(); } } } /**
* Esta prueba utiliza el soporte JTA para manejar transacciones. */
public void run() { Connection c = null;
try {
Context ctx = new InitialContext();
// Presuponer que el origen de datos se apoya en un UDBXADataSource. UDBXADataSource ds = (UDBXADataSource) ctx.lookup("XADataSource"); // Desde el DataSource, obtener un objeto XAConnection que
// contiene un XAResource y un objeto Connection. XAConnection xaConn = ds.getXAConnection(); XAResource xaRes = xaConn.getXAResource(); Connection c = xaConn.getConnection(); Statement stmt = c.createStatement();
// Para transacciones XA, es necesario un identificador de transacción. // Esto no implica que todos los XID sean iguales.
// Cada XID debe ser exclusivo para distinguir las diversas transacciones // que se producen.
// El soporte para crear XID se deja de nuevo al // programa de aplicación.
Xid xid1 = JDXATest.xidFactory(); Xid xid2 = JDXATest.xidFactory(); Xid xid3 = JDXATest.xidFactory();
// Realizar el trabajo bajo tres transacciones para esta conexión. xaRes.start(xid1, XAResource.TMNOFLAGS);
int count1 = stmt.executeUpdate("INSERT INTO CUJOSQL.JTATABLE VALUES(’Valor 1-A’)"); xaRes.end(xid1, XAResource.TMNOFLAGS);
xaRes.start(xid2, XAResource.TMNOFLAGS);
int count2 = stmt.executeUpdate("INSERT INTO CUJOSQL.JTATABLE VALUES(’Valor 1-B’)"); xaRes.end(xid2, XAResource.TMNOFLAGS);
xaRes.start(xid3, XAResource.TMNOFLAGS);
int count3 = stmt.executeUpdate("INSERT INTO CUJOSQL.JTATABLE VALUES(’Valor 1-C’)"); xaRes.end(xid3, XAResource.TMNOFLAGS);
// Preparar todas las transacciones int rc1 = xaRes.prepare(xid1); int rc2 = xaRes.prepare(xid2); int rc3 = xaRes.prepare(xid3);
// El intento de insertar el segundo valor en la tabla // no se compromete. xaRes.commit(xid1, false); xaRes.rollback(xid2); xaRes.commit(xid3, false); } catch (Exception e) { System.out.println("Algo ha fallado."); e.printStackTrace(); } finally { try { if (c != null) c.close(); } catch (SQLException e) {
System.out.println("Nota: Excepción de limpieza."); e.printStackTrace();
} } } }
Ejemplo: ResultSets suspendidos:
Este es un ejemplo de cómo se reprocesa un objeto Statement bajo otra transacción para realizar el trabajo.
Ejemplo: ResultSets suspendidos
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
import java.sql.*; import javax.sql.*; import java.util.*; import javax.transaction.*; import javax.transaction.xa.*; import com.ibm.db2.jdbc.app.*; public class JTATxEffect {
public static void main(java.lang.String[] args) { JTATxEffect test = new JTATxEffect();
test.setup(); test.run(); }
/**
* Manejar la ejecución de limpieza anterior para que esta prueba pueda volver a empezar. */
public void setup() { Connection c = null; Statement s = null;
try {
Class.forName(″com.ibm.db2.jdbc.app.DB2Driver″);
c = DriverManager.getConnection(″jdbc:db2:*local″); s = c.createStatement();
try {
s.executeUpdate(″DROP TABLE CUJOSQL.JTATABLE″); } catch (SQLException e) {
// Ignorar... no existe }
s.executeUpdate(″CREATE TABLE CUJOSQL.JTATABLE (COL1 CHAR (50))″); s.executeUpdate(″INSERT INTO CUJOSQL.JTATABLE VALUES(’Fun with JTA’)″); s.executeUpdate(″INSERT INTO CUJOSQL.JTATABLE VALUES(’JTA is fun.)″); s.close(); } finally { if (c != null) { c.close(); } } } /**
* Esta prueba utiliza el soporte JTA para manejar transacciones. */
public void run() { Connection c = null;
try {
Context ctx = new InitialContext();
// Presuponer que el origen de datos se apoya en un UDBXADataSource. UDBXADataSource ds = (UDBXADataSource) ctx.lookup(″XADataSource″); // Desde el DataSource, obtener un objeto XAConnection que
// contiene un XAResource y un objeto Connection. XAConnection xaConn = ds.getXAConnection(); XAResource xaRes = xaConn.getXAResource(); Connection c = xaConn.getConnection();
// Para transacciones XA, es necesario un identificador de transacción. // No se incluye una implementación de la interfaz XID con
// el controlador JDBC. Consulte “Transacciones con JTA” en la página 111 // para obtener una descripción de esta interfaz para crear una
// clase para ella. Xid xid = new XidImpl();
// La conexión de XAResource puede utilizarse como // cualquier otra conexión JDBC.
Statement stmt = c.createStatement();
// Debe informarse al recurso XA antes de iniciar cualquier // trabajo transaccional.
// Crear un ResultSet durante el proceso de JDBC y extraer una fila. ResultSet rs = stmt.executeUpdate(″SELECT * FROM CUJOSQL.JTATABLE″); rs.next();
// Se llama al método end con la opción suspend. Los
// ResultSets asociados con la transacción actual quedan ’suspendidos’. // En este estado, no se eliminan ni son accesibles.
xaRes.end(xid, XAResource.TMSUSPEND);
// Mientras tanto, pueden realizarse otras tareas fuera de la // transacción.
// Los ResultSets bajo la transacción pueden cerrarse si // se reutiliza el objeto Statement utilizado para crearlos.
ResultSet nonXARS = stmt.executeQuery(″SELECT * FROM CUJOSQL.JTATABLE″); while (nonXARS.next()) {
// Procesar aquí... }
// Intento de volver a la transacción suspendida. El ResultSet // de la transacción suspendida ha desaparecido debido a que // la sentencia se ha procesado de nuevo.
xaRes.start(newXid, XAResource.TMRESUME); try {
rs.next();
} catch (SQLException ex) {
System.out.println(″Esta excepción se esperaba. El ResultSet se ha cerrado debido a otro proces }
// Cuando la transacción termine, finalizarla // y comprometer el trabajo que contenga. xaRes.end(xid, XAResource.TMNOFLAGS); int rc = xaRes.prepare(xid); xaRes.commit(xid, false); } catch (Exception e) { System.out.println(″Algo ha fallado.″); e.printStackTrace(); } finally { try { if (c != null) c.close(); } catch (SQLException e) {
System.out.println(″Nota: Excepción de limpieza.″); e.printStackTrace();
} } } }
Ejemplo: finalizar una transacción:
Este es un ejemplo de cómo finalizar una transacción en la aplicación.
Ejemplo: finalizar una transacción
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
import java.sql.*; import javax.sql.*; import java.util.*; import javax.transaction.*; import javax.transaction.xa.*; import com.ibm.db2.jdbc.app.*; public class JTATxEnd {
public static void main(java.lang.String[] args) { JTATxEnd test = new JTATxEnd();
test.setup(); test.run(); }
/**
* Manejar la ejecución de limpieza anterior para que esta prueba pueda volver a empezar. */
public void setup() { Connection c = null; Statement s = null; try { Class.forName(″com.ibm.db2.jdbc.app.DB2Driver″); c = DriverManager.getConnection(″jdbc:db2:*local″); s = c.createStatement(); try {
s.executeUpdate(″DROP TABLE CUJOSQL.JTATABLE″); } catch (SQLException e) {
// Ignorar... no existe }
s.executeUpdate(″CREATE TABLE CUJOSQL.JTATABLE (COL1 CHAR (50))″); s.executeUpdate(″INSERT INTO CUJOSQL.JTATABLE VALUES(’Fun with JTA’)″); s.executeUpdate(″INSERT INTO CUJOSQL.JTATABLE VALUES(’JTA is fun.)″); s.close(); } finally { if (c != null) { c.close(); } } }
/**
* Esta prueba utiliza el soporte JTA para manejar transacciones. */
public void run() { Connection c = null;
try {
Context ctx = new InitialContext();
// Presuponer que el origen de datos se apoya en un UDBXADataSource. UDBXADataSource ds = (UDBXADataSource) ctx.lookup(″XADataSource″); // Desde el DataSource, obtener un objeto XAConnection que
// contiene un XAResource y un objeto Connection. XAConnection xaConn = ds.getXAConnection(); XAResource xaRes = xaConn.getXAResource(); Connection c = xaConn.getConnection();
// Para transacciones XA, es necesario un identificador de transacción. // No se incluye una implementación de la interfaz XID con