Gestionnaire de transactions externes

En général, les transactions eXtreme Scale débutent par la méthode Session.begin et finissent par la méthode Session.commit. Toutefois, lorsqu'une ObjectGrid est imbriquée, un coordinateur de transactions externes peut débuter et terminer les transactions. Dans ce cas, il n'est pas nécessaire d'appeler les méthodes begin ou commit.

Coordination de transactions externes

Le plug-in TransactionCallback est étendu avec la méthode isExternalTransactionActive(Session session) qui associe le session eXtreme Scale à une transaction externe. L'en-tête de méthode est la suivante :

isExternalTransactionActive(Session session) booléen synchronisé public

Par exemple, eXtreme Scale peut être configuré pour une intégration avec WebSphere Application Server et WebSphere Extended Deployment.

En outre, eXtreme Scale offre un plug-in intégré, désigné sous le nom de WebSphere Plug-in de gestion des événements du cycle de vie des transactions, qui décrit comment créer le plug-in pour les environnements WebSphere Application Server bien qu'il soit possible d'adapter le plug-in pour d'autres infrastructures.

Cette intégration transparente repose essentiellement sur l'exploitation de l'API ExtendedJTATransaction dans WebSphere Application Server version 5.x et version 6.x. Toutefois, si vous utilisez WebSphere Application Server version 6.0.2, vous devez appliquer le correctif APAR PK07848 pour prendre en charge cette méthode. Utilisez l'exemple de code ci-dessous pour associer une session ObjectGrid avec un ID de transaction WebSphere Application Server :
/**
* Cette méthode est requise pour associer une session objectGrid avec un ID de transaction WebSphere 
* Application Server.
*/
Map/**/ localIdToSession;
public synchronized boolean isExternalTransactionActive(Session session)
{
    // gardez à l'esprit que cet ID local implique l'enregistrement de cette session pour une utilisation ultérieure.
    localIdToSession.put(new Integer(jta.getLocalId()), session);
    return true;
}

Extraction d'une transaction externe

Il est parfois conseillé d'extraire un objet de service de transaction externe pour le plug-in TransactionCallback à utiliser. Sur le serveur WebSphere Application Server,consultez l'objet ExtendedJTATransaction à partir de son espace de noms, tel qu'illustré dans l'exemple suivant :
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");
    }
}

Pour d'autres produits, vous pouvez utiliser une approche similaire pour extraire l'objet de service de transaction.

Validation de contrôle par rappel externe

Le plug-in TransactionCallback doit recevoir un signal externe pour valider ou annuler la session eXtreme Scale. Pour ce faire, utilisez le rappel du service de transaction externe. Implémentez l'interface de rappel externe et enregistrez-la auprès du service de transaction externe. Par exemple, à l'aide de WebSphere Application Server, implémentez l'interface SynchronizationCallback, tel qu'illustré dans l'exemple suivant :
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);
      // trouver la session pour l'ID local
      Session session = (Session)localIdToSession.get(lid);
      if(session != null) {
         	try {
            // si WebSphere Application Server est validé lors du 
            // renforcement de la transaction dans la mappe de sauvegarde.
            // Nous avons déjà effectué un vidage dans beforeCompletion
            if(didCommit) {
               session.commit();
            } else {
               // otherwise rollback
               session.rollback();
            }
         } catch(NoActiveTransactionException e) {
            // impossible en théorie
         } catch(TransactionException e) {
            // ne devrait pas échouer étant donné le vidage
         } finally {
            // efface toujours la session de la mappe.
            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 ne définit pas formellement 
            // une méthode pour signaler
            // que la transaction a échoué, donc procédez comme suit
            throw new RuntimeException("Cache flush failed", e);
         }
      }
   }
}

Utilisation des API eXtreme Scale avec le plug-in TransactionCallback

Le plug-in TransactionCallback désactive la validation automatique dans eXtreme Scale. Le modèle d'utilisation normal pour une API eXtreme Scale est le suivant :
Session ogSession = ...;
ObjectMap myMap = ogSession.getMap("MyMap");
ogSession.begin();
MyObject v = myMap.get("key");
v.setAttribute("newValue");
myMap.update("key", v);
ogSession.commit();
Lorsque ce plug-in TransactionCallback est utilisé, eXtreme Scale considère que l'application utilise l'API eXtreme Scale lorsqu'une transaction gérée par conteneur est identifiée. L'extrait de code précédent modifie le code ci-dessous dans cet environnement :
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();
}

La méthode myMethod s'apparente à un scénario d'application Web. L'application utilise l'interface UserTransaction classique pour commencer, valider et annuler les transactions. L'API eXtreme Scale commence et valide automatiquement la transaction gérée par conteneur. Si la méthode est une méthode EJB (Enterprise JavaBeans) utilisant l'attribut TX_REQUIRES, supprimez la référence UserTransaction et les appels pour commencer et valider les transactions et vous constaterez que la méthode fonctionnera de la même manière. Dans ce cas, le conteneur se charge de démarrer et d'arrêter la transaction.