7.7.4. Comportement de transaction des invocations EJB
7.7.4. Comportement de transaction des invocations EJB
Invocations de serveur à serveur
Les attributs de transaction d'applications distribuées EAP doivent être gérés comme si l'application était appelée sur le même serveur. Pour mettre fin à une transaction, la méthode de destination doit comporter la mention REQUIRES_NEW, à l'aide d'interfaces différentes.
Note
EAP 6 n'a pas besoin de JTS ( de l'anglais Java Transaction Services) pour la propagation de la transaction sur les invocations EJB d'un serveur à l'autre si les deux serveurs sont EAP 6. La bibliothèque d'API cliente de JBoss EJB la gère elle-même.
Les invocations côté client
Pour invoquer les beans de session EJB avec un client EAP 6 autonome, le client doit avoir une référence à l'objet InitialContext tandis que les proxies EJB ou UserTransaction sont utilisés. Il est également important de garder l'objet InitialContext ouvert tant que les proxies EJB ou UserTransaction sont utilisés. Le contrôle des connexions se fera à l'intérieur des classes créées par InitialContext avec les propriétés.
L'exemple suivant vous montre l'API du client EJB qui contient la référence à l'objet InitialContext :
package org.jboss.as.quickstarts.ejb.multi.server;
import java.util.Date;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.jboss.as.quickstarts.ejb.multi.server.app.MainApp;
import org.jboss.ejb.client.ContextSelector;
import org.jboss.ejb.client.EJBClientConfiguration;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;
public class Client {
/**
* @param args no args needed
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// suppress output of client messages
Logger.getLogger("org.jboss").setLevel(Level.OFF);
Logger.getLogger("org.xnio").setLevel(Level.OFF);
Properties p = new Properties();
p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
p.put("remote.connections", "one");
p.put("remote.connection.one.port", "4447");
p.put("remote.connection.one.host", "localhost");
p.put("remote.connection.one.username", "quickuser");
p.put("remote.connection.one.password", "quick-123");
EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(p);
ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
EJBClientContext.setSelector(selector);
Properties props = new Properties();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext context = new InitialContext(props);
final String rcal = "ejb:jboss-ejb-multi-server-app-main/ejb//" + ("MainAppBean") + "!" + MainApp.class.getName();
final MainApp remote = (MainApp) context.lookup(rcal);
final String result = remote.invokeAll("Client call at "+new Date());
System.out.println("InvokeAll succeed: "+result);
}
}
package org.jboss.as.quickstarts.ejb.multi.server;
import java.util.Date;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.jboss.as.quickstarts.ejb.multi.server.app.MainApp;
import org.jboss.ejb.client.ContextSelector;
import org.jboss.ejb.client.EJBClientConfiguration;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;
public class Client {
/**
* @param args no args needed
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// suppress output of client messages
Logger.getLogger("org.jboss").setLevel(Level.OFF);
Logger.getLogger("org.xnio").setLevel(Level.OFF);
Properties p = new Properties();
p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
p.put("remote.connections", "one");
p.put("remote.connection.one.port", "4447");
p.put("remote.connection.one.host", "localhost");
p.put("remote.connection.one.username", "quickuser");
p.put("remote.connection.one.password", "quick-123");
EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(p);
ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
EJBClientContext.setSelector(selector);
Properties props = new Properties();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext context = new InitialContext(props);
final String rcal = "ejb:jboss-ejb-multi-server-app-main/ejb//" + ("MainAppBean") + "!" + MainApp.class.getName();
final MainApp remote = (MainApp) context.lookup(rcal);
final String result = remote.invokeAll("Client call at "+new Date());
System.out.println("InvokeAll succeed: "+result);
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Note
L'obtention d'une réféence UserTransaction sur un client n'est pas prise en charge pour les scénarios de contextes client EJB scoped et pour les invocations qui utilisent le protocole remote-naming. C'est parce que dans ces scénarios, InitialContext encapsule sa propre instance de contexte client, à laquelle on ne peut pas accéder par les méthodes statiques de la classe EJBClient. Quand la méthode EJBClient.getUserTransaction() est invoquée, elle renvoie une transaction en provenance du contexte client EJB (global) par défaut (pas forcément initialisé) et non pas en provenance du contexte souhaité.
Référence UserTransaction côté client
L'exemple suivant vous montre comment obtenir une référence UserTransaction sur un client autonome :
import org.jboss.ejb.client.EJBClient;
import javax.transaction.UserTransaction;
.
.
Context context=null;
UserTransaction tx=null;
try {
Properties props = new Properties();
// REMEMBER: there must be a jboss-ejb-client.properties with the connection parameter
// in the clients classpath
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
context = new InitialContext(props);
System.out.println("\n\tGot initial Context: "+context);
tx=EJBClient.getUserTransaction("yourServerName");
System.out.println("UserTransaction = "+tx.getStatus());
tx.begin();
// do some work
...
}catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally{
if(context != null) {
context.close();
}
}
import org.jboss.ejb.client.EJBClient;
import javax.transaction.UserTransaction;
.
.
Context context=null;
UserTransaction tx=null;
try {
Properties props = new Properties();
// REMEMBER: there must be a jboss-ejb-client.properties with the connection parameter
// in the clients classpath
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
context = new InitialContext(props);
System.out.println("\n\tGot initial Context: "+context);
tx=EJBClient.getUserTransaction("yourServerName");
System.out.println("UserTransaction = "+tx.getStatus());
tx.begin();
// do some work
...
}catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally{
if(context != null) {
context.close();
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Note
Pour obtenir une référence UserTransaction côté client, démarrer votre serveur avec la propriété système suivante -Djboss.node.name=yourServerName et utilisez-la ensuite côté client comme suit :
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Remplacer "yourServerName" par le nom de votre serveur. Si une transaction utilisateur démarre sur un nœud, toutes les invocations seront sticky sur le nœud et le nœud devra avoir tous les EJB nécessaires. Il n'est pas possible d'utiliser UserTransaction avec un protocole de nommage à distance ou avec un scoped-context.
Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance. Découvrez nos récentes mises à jour.
Rendre l’open source plus inclusif
Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez le Blog Red Hat.
À propos de Red Hat
Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.