2017-07-18 30 views
0

J'ai un EJB impliqué dans une transaction globale. Il y a une partie du code qui, si elle échoue, je veux annuler explicitement, bien que je ne veux pas que toute la transaction échoue.Annulation de légende dans une transaction distribuée: possible?

Comme rollback est interdit dans un CMT J'ai créé un BMT et essayé le code suivant:

connection.setAutoCommit(false); 
Savepoint sp= connection.setSavepoint(); 
try{ 
    //my code editing DB that could possibly fail 
}catch(SomeException ex){ 
    connection.rollback(sp); 
} 

De cette façon, je défais tout simplement ma modification db locale mais je aussi ne se propagent pas ce ne parviennent pas à l'extérieur. Quoi qu'il en soit ce programme échoue avec comme:

« est interdite dans un point d'enregistrement d'une transaction distribuée »

Y at-il une autre approche pour résoudre ce problème?

Répondre

1

Le contexte de transaction n'est pas propagé à BTM. Votre bean ne fera pas non plus partie de la transaction globale. Ainsi, lorsque votre transaction globale échoue, vos modifications peuvent toujours être validées.

Je ne suis pas familier avec les paramètres de websphere mais je revérifierais si la connexion. Je m'attends à être injecté à la BTM ou est-ce que vous passez la connexion en quelque sorte de CMT? Je pourrais essayer de vérifier la configuration du conteneur si la connexion est configurée pour supporter jta/transaction globale. Ou commencez-vous le UserTransaction.begin() avant de commencer à travailler avec la connexion? Encore si cela fonctionne, cela ne résout pas votre problème. L'ajustement pour vous est l'utilisation de transactions imbriquées, mais elles ne sont pas prises en charge dans Java EE. Juste si WebShere a une manière spécifique de fournisseur comment les exécuter (je ne sais pas sa capacité).

Ensuite, la façon la plus simple est d'utiliser CMT REQUIRES_NEW mais il y a un inconvénient à ce que la modification de la base de données soit validée même si la transaction globale a été annulée.

Peut-être qu'une modification de la description de l'application serait nécessaire.

2

Vous pouvez utiliser CMT en utilisant un second EJB annoté avec @TransactionAttribute(REQUIRES_NEW), où vous placez le code qui peut échouer. Vous devez alors appeler cet EJB depuis l'autre EJB.

Le conteneur crée une nouvelle transaction pour le code et l'annulera s'il échoue.

+0

La nouvelle transaction sera également validée si cela fonctionne. Sachez simplement que la nouvelle transaction est indépendante de la première, et si quelque chose fait reculer la première transaction (pour une autre raison), la nouvelle pièce aura encore été validée. – kaczyns