Desarrollo de componentes de cliente de eXtreme Scale para utilizar transacciones

[Version 8.5 and later] El adaptador de recursos de WebSphere eXtreme Scale proporciona soporte para la gestión de conexiones de cliente y las transacciones locales. Con este soporte, las aplicaciones de Java Platform, Enterprise Edition (Java EE) pueden buscar las conexiones de cliente de eXtreme Scale y delimitar las transacciones locales con transacciones locales Java EE o las API de eXtreme Scale.

Antes de empezar

Cree una referencia de recursos de fábrica de conexiones de eXtreme Scale.

Acerca de esta tarea

Existen varias opciones para trabajar con las API de acceso a datos de eXtreme Scale. En todos los casos, la fábrica de conexiones de eXtreme Scale debe inyectarse en el componente de la aplicación, o buscarse en la Java Naming Directory Interface (JNDI). Una vez que se ha buscado la fábrica de conexiones, puede delimitar transacciones y crear conexiones para acceder a las API de eXtreme Scale.

Opcionalmente, puede difundir la instancia de javax.resource.cci.ConnectionFactory a un com.ibm.websphere.xs.ra.XSConnectionFactory que proporcione opciones adicionales para recuperar descriptores de conexiones. Los descriptores de conexiones resultantes deben difundirse a la interfaz com.ibm.websphere.xs.ra.XSConnection, que proporciona el método getSession. El método getSession devuelve un descriptor de objetos com.ibm.websphere.objectgrid.Session que permite a las aplicaciones utilizar cualquiera de las API de acceso a datos de eXtreme Scale, como por ejemplo la API ObjectMap y la API EntityManager.

El descriptor de sesiones y cualquier objeto derivado son válidos para toda la duración del descriptor de contexto XSConnection.

Se pueden utilizar los siguientes procedimientos para delimitar las transacciones de eXtreme Scale. No puede combinar cada uno de los procedimientos. Por ejemplo, no puede combinar la demarcación de transacciones globales y la demarcación de transacciones locales en un mismo contexto de componente de la aplicación.

Procedimiento

Ejemplo

Vea el siguiente código de ejemplo, que muestra los pasos anteriores para delimitar transacciones de eXtreme Scale.
    // (C) Copyright IBM Corp. 2001, 2012.
    // Reservados todos los derechos. Materiales bajo licencia - Propiedad de IBM.
    package com.ibm.ws.xs.ra.test.ee;
     
    	import javax.naming.InitialContext;
    import javax.resource.cci.Connection;
    import javax.resource.cci.ConnectionFactory;
    import javax.resource.cci.LocalTransaction;
    import javax.transaction.Status;
    import javax.transaction.UserTransaction;
     
    import junit.framework.TestCase;
     
    import com.ibm.websphere.objectgrid.ObjectMap;
    import com.ibm.websphere.objectgrid.Session;
    import com.ibm.websphere.xs.ra.XSConnection;
     
    /**
    * Este ejemplo requiere que se ejecuta en un contexto J2EE en su
    * servidor de aplicaciones. Por ejemplo, mediante el servlet de infraestructura JUnitEE.
    *
    * El código de estos métodos de prueba normalmente reside en su propio servlet,
    * EJB u otro componente web.
    *
    * El ejemplo depende de una fábrica de conexiones de WebSphere eXtreme Scale
    * configurada y registrada en el nombre JNDI de "eis/embedded/wxscf" que define
    * una conexión a una cuadrícula con una correlación llamada "Map1".
    *
    * El ejemplo realiza una búsqueda directa del nombre JNDI y no requiere
    * inyección de recursos.
    */
    public class DocSampleTests extends TestCase {
        public final static String CF_JNDI_NAME = "eis/embedded/wxscf";
        public final static String MAP_NAME = "Map1";
       
        Long                key = null;
        Long                value = null;
        InitialContext      ctx = null;
        ConnectionFactory   cf = null;
       
        public DocSampleTests() {
        }
        public DocSampleTests(String name) {
            super(name);
        }
        protected void setUp() throws Exception {
            ctx = new InitialContext();
            cf = (ConnectionFactory)ctx.lookup(CF_JNDI_NAME);
            key = System.nanoTime();
            value = System.nanoTime();
        }
        /**
         * Este ejemplo se ejecuta cuando no está en un contexto de transacción global
         * y utiliza la confirmación automática.
         */
        public void testLocalAutocommit() throws Exception {
            Connection conn = cf.getConnection();
            try {
                Session    session = ((XSConnection)conn).getSession();
                ObjectMap  map = session.getMap(MAP_NAME);
                map.insert(key, value); // O varias operacciones de acceso a datos
            }
            finally {
                conn.close();
            }
        }
     
        /**
         * Este ejemplo se ejecuta cuando no está en un contexto de transacción global
         * y delimita la transacción mediante session.begin()/session.commit()
         */
        public void testLocalSessionTransaction() throws Exception {
            Session session = null;
            Connection conn = cf.getConnection();
            try {
                session = ((XSConnection)conn).getSession();
                		session.begin();
                ObjectMap  map = session.getMap(MAP_NAME);
                map.insert(key, value); // O varias operacciones de acceso a datos
                		session.commit();
            }
            finally {
                if (session != null && session.isTransactionActive()) {
                    try { session.rollback(); }
                    catch (Exception e) { e.printStackTrace(); }
                }
                conn.close();
            }
        }
       
        /**
         * Este ejemplo utiliza la interfaz LocalTransaction para delimitar
         * transacciones.
         */
        public void testLocalTranTransaction() throws Exception {
            LocalTransaction tx = null;
            Connection conn = cf.getConnection();
            try {
                tx = conn.getLocalTransaction();
                tx.begin();
                Session    session = ((XSConnection)conn).getSession();
                ObjectMap  map = session.getMap(MAP_NAME);
                map.insert(key, value); // O varias operacciones de acceso a datos
                tx.commit(); tx = null;
            }
            finally {
                if (tx != null) {
                    try { tx.rollback(); }
                    catch (Exception e) { e.printStackTrace(); }
                }
                conn.close();
            }
        }
       
        /**
         * Este ejemplo depende de una transacción gestionada externamente,
         * la cual puede estar presente generalmente en
         * un EJB con sus atributos de transacción establecidos en REQUIRED o REQUIRES_NEW.
         * NOTA: Si NO hay ninguna transacción global activa, este ejemplo se ejecuta en
         *       la modalidad de confirmación automática porque no verifica si existe una transacción.
         */
        public void testGlobalTransactionContainerManaged() throws Exception {
            Connection      conn = cf.getConnection();
            try {
                Session    session = ((XSConnection)conn).getSession();
                ObjectMap  map = session.getMap(MAP_NAME);
                map.insert(key, value); // O varias operacciones de acceso a datos
            }
            catch (Throwable t) {
                t.printStackTrace();
                UserTransaction tx = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
                if (tx.getStatus() != Status.STATUS_NO_TRANSACTION) {
                    tx.setRollbackOnly();
                }
            }
            finally {
                conn.close();
            }
        }
       
        /**
         * Este ejemplo muestra el inicio de una nueva transacción global mediante
         * la interfaz UserTransaction. Normalmente, el contenedor inicia la
         * transacción global (por ejemplo, en un EJB con un atributo de transacción
         * REQUIRES_NEW), pero este ejemplo también iniciará la transacción global
         * mediante la API UserTransaction si no está activa actualmente.
         */
        public void testGlobalTransactionTestManaged() throws Exception {
            boolean         started = false;
            UserTransaction tx = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
            if (tx.getStatus() == Status.STATUS_NO_TRANSACTION) {
                tx.begin();
                started = true;
            }
            // else { called with an externally/container managed transaction }
            Connection conn  = null;
            try {
                conn = cf.getConnection(); // Obtener transacción tras el inicio de la transacción global
                Session    session = ((XSConnection)conn).getSession();
                ObjectMap  map = session.getMap(MAP_NAME);
                map.insert(key, value); // O varias operacciones de acceso a datos
                if (started) {
                    tx.commit(); started = false; tx = null;
                }
            }
            finally {
                if (started) {
                    try { tx.rollback(); }
                    catch (Exception e) { e.printStackTrace(); }
                }
                if (conn != null) { conn.close(); }   
            }
        }
    }