Gestores de transacciones externas

Normalmente, las transacciones eXtreme Scale empiezan con el método Session.begin y finalizan con el método Session.commit. Sin embargo, cuando se incorpora un ObjectGrid, un coordinador de transacciones externas puede iniciar y finalizar transacciones. En este caso, no es necesario llamar a los métodos begin o commit.

Coordinación de transacciones externas

El plug-in TransactionCallback se amplía con el método isExternalTransactionActive(Session session) que asocia la sesión de eXtreme Scale con una transacción externa. La cabecera del método es la siguiente:

public synchronized boolean isExternalTransactionActive(Session session)

Por ejemplo, eXtreme Scale se puede configurar para integrarse con WebSphere Application Server y WebSphere Extended Deployment.

Además, eXtreme Scale proporciona un plug-in incorporado llamado WebSphere Plug-ins para gestionar los sucesos del ciclo de vida de transacciones, que describe cómo generar el plug-in para los entornos de WebSphere Application Server, pero puede adaptar el plug-in para otras infraestructuras.

La clave de esta integración sin fisuras es la explotación de la API ExtendedJTATransaction en WebSphere Application Server versión 5.x y versión 6.x. Sin embargo, si utiliza WebSphere Application Server versión 6.0.2, debe aplicar el APAR PK07848 para soportar este método. Utilice el siguiente código de ejemplo para asociar a un objeto ObjectGrid con un ID de transacción de WebSphere Application Server:
/**
* Este método es necesario para asociar una sesión de objectGrid con un ID de
* transacción de WebSphere Application Server.
*/
Map/**/ localIdToSession;
public synchronized boolean isExternalTransactionActive(Session session)
{
    // recuerde que este localid significa que la sesión se ha guardado para
ser utilizada más tarde.
    localIdToSession.put(new Integer(jta.getLocalId()), session);
    return true;
}

Recuperación de una transacción externa

A veces, es posible que tenga que recuperar un objeto de servicio de transacción externa para que lo utilice el plug-in TransactionCallback. En el servidor WebSphere Application Server, busque el objeto ExtendedJTATransaction en su espacio de nombres, tal como se muestra en el ejemplo siguiente:
public J2EETransactionCallback() {
    super();
    localIdToSession = new HashMap();
    String lookupName="java:comp/websphere/ExtendedJTATransaction";
    try
    {
        InitialContext ic = new InitialContext();
        jta = (ExtendedJTATransaction)ic.lookup(lookupName);
        jta.registerSynchronizationCallback(this);
    }
    catch(NotSupportedException e)
    {
        throw new RuntimeException("Cannot register jta callback", e);
    }
    catch(NamingException e){
        throw new RuntimeException("Cannot get transaction object");
    }
}

Para otros productos, puede utilizar un acercamiento similar para recuperar el objeto de servicio de transacción.

Control de la confirmación mediante la devolución de llamada externa

El plug-in TransactionCallback debe recibir una señal externa para confirmar o retrotraer la sesión de eXtreme Scale. Para recibir esta señal externa, utilice la devolución de llamada del servicio de transacción externa. Implemente la interfaz de devolución de llamada externa y regístrela con el servicio de transacción externa. Por ejemplo, con WebSphere Application Server, implemente la interfaz SynchronizationCallback, tal como se muestra en el ejemplo siguiente:
public class J2EETransactionCallback implements 
	com.ibm.websphere.objectgrid.plugins.TransactionCallback, SynchronizationCallback {
   public J2EETransactionCallback() {
      super();
      String lookupName="java:comp/websphere/ExtendedJTATransaction";
      localIdToSession = new HashMap();
      try {
         InitialContext ic = new InitialContext();
         jta = (ExtendedJTATransaction)ic.lookup(lookupName);
         jta.registerSynchronizationCallback(this);
      } catch(NotSupportedException e) {
         throw new RuntimeException("Cannot register jta callback", e);
      }
      catch(NamingException e) {
         throw new RuntimeException("Cannot get transaction object");
      }
   }

   public synchronized void afterCompletion(int localId, byte[] arg1,boolean didCommit) {
      Integer lid = new Integer(localId);
      // buscar localId de Session
      Session session = (Session)localIdToSession.get(lid);
      if(session != null) {
         	try {
            // si WebSphere Application Server se confirma al
            // proteger la transacción para backingMap.
            // Se realizó un vaciado en beforeCompletion
            if(didCommit) {
               session.commit();
            } else {
               // de lo contrario, retrotraer
               session.rollback();
            }
         } catch(NoActiveTransactionException e) {
            // imposible en teoría
         } catch(TransactionException e) {
            // como ya se ha hecho un vaciado, no debería producirse error
         } finally {
            // siempre borra la sesión de la correlación
            localIdToSession.remove(lid);
         }
      }
   }

   public synchronized void beforeCompletion(int localId, byte[] arg1) {
      Session session = (Session)localIdToSession.get(new Integer(localId));
      if(session != null) {
         try {
            session.flush();
         } catch(TransactionException e) {
            // WebSphere Application Server no define formalmente
            // una manera de indicar que la
            // transacción ha fallado, por lo que debe hacer esto
            throw new RuntimeException("Cache flush failed", e);
         }
      }
   }
}

Utilice las API de eXtreme Scale con el plug-in TransactionCallback

El plug-in TransactionCallback inhabilita la confirmación automática en eXtreme Scale. El patrón de uso normal para un eXtreme Scale es el siguiente:
Session ogSession = ...;
ObjectMap myMap = ogSession.getMap("MyMap");
ogSession.begin();
MyObject v = myMap.get("key");
v.setAttribute("newValue");
myMap.update("key", v);
ogSession.commit();
Cuando se utiliza este plug-in TransactionCallback, eXtreme Scale presupone que la aplicación utiliza eXtreme Scale cuando está presente una transacción gestionada por contenedor. El fragmento de código anterior cambia el siguiente código en este entorno:
public void myMethod() {
   UserTransaction tx = ...;
   tx.begin();
   Session ogSession = ...;
   ObjectMap myMap = ogSession.getMap("MyMap");
   yObject v = myMap.get("key");
   v.setAttribute("newValue");
   myMap.update("key", v);
   tx.commit();
}

El método myMethod es similar a un escenario de aplicación web. La aplicación utiliza la interfaz UserTransaction normal para empezar, confirmar y retrotraer transacciones. eXtreme Scale se inicia y se confirma automáticamente cerca de la transacción de contenedor. Si el método es un método EJB (Enterprise JavaBeans) que utiliza el atributo TX_REQUIRES, elimine la referencia de UserTransaction y las llamadas para iniciar y confirmar transacciones y el método funcionan del mismo modo. En este caso, el contenedor es responsable de iniciar y terminar la transacción.