2009-05-05 5 views
2

Je travaille sur un programme qui utilise Spring et obtient les transactions Hibernate de manière transparente en utilisant un TransactionInterceptor. Cela rend très pratique de dire "quand cette méthode est invoquée à partir d'une autre classe, enveloppez-la dans une transaction si elle n'en est pas déjà une."Obtention d'une transaction Hibernate dans une classe Spring

Cependant, j'ai une classe qui doit tenter une écriture et doit savoir immédiatement si elle a réussi ou non. Bien que je veuille deux méthodes de toute façon, j'espérais qu'il y avait un moyen de les garder dans la même classe sans avoir besoin de créer explicitement une transaction procédurale. En effet, je voudrais quelque chose comme ceci:

public void methodOne() { 
    //..do some stuff 
    try { 
     transactionalMethod();//won't do what I want 
    } catch(OptimisticLockingFailure e) { 
     //..recover 
    } 
} 

@Transactional 
public void transactionalMethod() { 
    //...do some stuff to database 
} 

Malheureusement, si je comprends bien, cela ne fonctionnerait pas parce que je venais d'appeler directement transactionalMethod. Y at-il un moyen de demander à Spring d'appeler une méthode locale pour moi et de l'emballer dans une transaction si nécessaire, ou est-ce que ça doit être dans une autre classe que je fil à celle-ci?

Répondre

1

Définir une interface que la classe implémente qui fait le transactionalMethod(); utiliser l'injection de dépendance pour définir la valeur de cette classe sur sa propre implémentation; dans votre fabrique de haricots, autorisez Spring à insérer un aspect Around autour de cette implémentation d'interface. Cela devrait fonctionner pour vos besoins.

0

Si vous souhaitez que le transactionalMethod fasse partie de sa propre transaction et ne se contente pas de participer à la transaction déjà active, vous devez définir la propagation sur REQUIRES_NEW. Comme si

@Transactional(propagation = Propagation.REQUIRES_NEW) 
public void transactionalMethod() { 
    //...do some stuff to database 
} 

Vous devez également vérifier que votre gestionnaire de transactions prend en charge cette propagation. les moyens que transactionalMethos est complètement séparé de l'autre transaction à laquelle il a été appelé et il commettra/rollback complètement aussi bien séparément.

Questions connexes