Comment prévenir la JPA de restauration transaction?
Méthodes invoquées sont les suivantes:
1. Struts Action
2. Classe de Service (méthode annotée par @Transactionnelle)
3. Xfire webservice appel
Tout, y compris les entretoises (DelegatingActionProxy) et des opérations est configuré avec le Printemps.
La persistance est fait avec JPA/Hibernate.
Parfois le webservice va jeter un décoché exception. Je attraper cette exception et de jeter un checked exception. Je ne veux pas la transaction, afin de faire reculer depuis le service web exception des changements de l'état actuel. J'ai annoté de la méthode comme ceci:
@Transactional(noRollbackFor={XFireRuntimeException.class, Exception.class})
public ActionForward callWS(Order order, ....) throws Exception
(...)
OrderResult orderResult = null;
try {
orderResult = webService.order(product, user)
} catch (XFireRuntimeException xfireRuntimeException) {
order.setFailed(true);
throw new WebServiceOrderFailed(order);
} finally {
persist(order);
}
}
J'obtiens toujours cette exception:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
Quand j'ai essayer de reproduire cela avec junit, la transaction n'est pas marqué pour la faire reculer et il est toujours possible de valider la transaction.
Comment puis-je faire le Printemps à ne pas annuler la transaction?
OriginalL'auteur D. Wroblewski | 2009-11-09
Vous devez vous connecter pour publier un commentaire.
Réussi à créer un cas de test pour ce problème:
FakeService:
WebService:
Cela va recréer la restauration-exception à la règle.
Puis j'ai réalisé que la transaction est probablement marqué comme rollbackOnly dans WebService.letsThrowAnException depuis WebService est également transactionnelle. J'ai déménagé à l'annotation:
Maintenant la transaction n'a pas été annulée et je peux valider les modifications apportées à l'Ordre.
OriginalL'auteur D. Wroblewski
Vous ne devez pas jeter une exception où le Printemps peut le voir. Dans ce cas, vous ne devez pas jeter
WebServiceOrderFailed()
. La solution est de diviser le code en deux méthodes. La première méthode ne permet la gestion d'erreur et renvoie l'exception, la méthode extérieure crée la transaction.[EDIT] Comme pour
noRollbackFor
: Essayer de remplacerException.class
avecWebServiceOrderFailed.class
.noRollbackFor
contrôles spécifiés classe d'exception et toutes ses sous-classes: static.springsource.org/spring/docs/2.5.x/api/org/... en Outre, par cochée par défaut exceptions n'entraînera PAS l'annulation: static.springsource.org/spring/docs/2.5.x/reference/...Cela n'explique pas pourquoi le code ci-dessus les rouleaux de retour sur
WebServiceOrderFailed
.Ma conjecture est que WebServiceOrderFailed est une RuntimeException et le code ci-dessus (
noRollbackFor={..., Exception.class}
) ne peut avoir aucun effet depuis l'Exception est traitée spécialement (dans le cas contraire, l'héritage de code serait aussi ignorer les RuntimeException puisqu'il s'étend Exception).Merci pour vos commentaires. Vous les gars m'a orienté dans la bonne direction! (WebServiceOrderFailed s'étend Exception, c'est un checked exception)
Aide gentiment que je suis face au même problème stackoverflow.com/questions/54343137/...
OriginalL'auteur Aaron Digulla