2009-09-04 8 views
0

Je vais essayer de décrire la situation. Nous avons un service web à chaque demande, le service Web démarre une transaction JTA. Il effectue plusieurs appels de base de données via la source de données XA et appelle d'autres services Web (hors contexte de transaction) et effectue également quelques appels EJB distants sur un autre serveur. Le problème est que le conteneur semble essayer d'impliquer EJB dans la transaction (et cela semble logique), mais en fait je veux qu'il ne participe pas à cette transaction car quand il participe à cette transaction, il expire toujours dans le phase de validation finale, mais quand j'exclus l'appel d'EJB cela fonctionne très bien.Effectuer un appel EJB sans transaction dans une transaction

Je ne peux pas modifier l'implémentation d'EJB et contrôler uniquement le code de service Web. Donc, ma question est: comment puis-je faire un appel EJB à l'EJB de transaction, mais hors de ma transaction JTA, mais toujours en transaction JTA pour d'autres ressources XA? J'espère avoir clarifié ma question :)

EDIT: Essayer de le rendre plus clair l'exemple pseudo-code:

// Begin transaction 
UserTransaction tx = (UserTransaction) ctx.lookup(USER_TRANSACTION); 
tx.begin(); 

// Do some database operations on XA datasource 

// Call remote EJB which has transcation attribute set to 'Supports' 
AccountInfo account = accountEjb.getAccountInfo(userId, accountId); // <-- Is it possible to make this to be not be part of user transction? 

// Do some more database operations on XA datasource 

// Commit transaction 
tx.commit(); 
+0

pourquoi ne pas augmenter le délai d'attente? –

+0

car le problème n'est pas dans le délai d'expiration, tous les appels passent juste ok dans les millisecondes, mais lorsque la transaction est validée à la fin, il expire, si l'appel ejb est retiré de la séquence d'appel, il valide ok. Donc, je pense qu'il doit faire quelque chose avec la communication inter-serveur, mais pas la valeur du timeout. –

Répondre

2

Vous pouvez créer un autre bean avec un attribut de transaction approprié. Ce bean peut déléguer tous les appels au premier bean.

Vous pouvez également appeler cet ejb à partir d'un autre thread.

+0

Je vais essayer d'utiliser un autre thread. –

1

transaction EJB est déclarative: pour un déploiement donné d'un EJB donné, vous spécifiez la sémantique de transaction. L'EJB exact peut être déployé (sous un nom différent, bien sûr) et vous pouvez spécifier différentes exigences pour ce déploiement. Cela suppose que (a) vous avez au moins le jar pour l'ejb, et, (b) que l'ejb en question est autonome et n'a pas de dépendances sur d'autres composants, et (c) le développeur de l'ejb hasn 't violé l'idée des transactions déclaratives et de ses travaux de haricot en dehors d'un contexte de transaction ainsi.

+0

Je ne peux pas contrôler l'EJB, mais je sais que son attribut de transaction est défini sur "Supports" et j'ai également effectué des appels autonomes (hors conteneur) vers cet EJB sans problème. EJB et mon service Web sont également déployés sur différents serveurs et je ne peux pas changer cela aussi. –

+0

Donc, ce n'est pas possible? –

0

Vous pouvez créer une autre méthode avec l'attribut approprié tx puis appelez avec par le proxy auto-injection (pseudo-code):

@Stateless 
public class LocalEJB1 { 

    @EJB 
    private LocalEJB1 localEJB1; 

    @EJB 
    private AccountEJB accountEjb; 

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
    public AccountInfo callNonTx() { 
     return accountEjb.getAccountInfo(userId, accountId); 
    } 

    public void yourCurrentMethod() { 
     // Begin transaction 
     UserTransaction tx = (UserTransaction) ctx.lookup(USER_TRANSACTION); 
     tx.begin(); 

     AccountInfo account = localEJB1.callNonTx(); 
     // Do some more database operations on XA datasource 

     // Commit transaction 
     tx.commit(); 
    } 
} 
Questions connexes