2010-08-26 38 views
5

Je suis en train d'ajouter des transactions déclaratives Spring via l'annotation @Transactional à un projet Java existant.Spring @Transactional est appliqué à la fois en tant que proxy Jdk dynamique et aspect aspectj

Lorsque j'ai rencontré un problème (sans rapport avec cette question), j'ai activé la journalisation complète du débogage. Curieusement, j'ai remarqué ce qui suit:

 
17:47:27,834 DEBUG HibernateTransactionManager:437 - Found thread-bound Session [[email protected]] for Hibernate transaction 
17:47:27,845 DEBUG HibernateTransactionManager:470 - Participating in existing transaction 
17:47:27,865 DEBUG AnnotationTransactionAttributeSource:106 - Adding transactional method 'updateUserProfile' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
17:47:27,875 DEBUG AnnotationTransactionAspect:321 - Skipping transactional joinpoint [se.myservice.UserService.updateUserProfile] because no transaction manager has been configured 

Après un certain débogage, j'ai découvert que les trois premières entrées du journal, où il est dit qu'il a trouvé une session liée fil et utilise cette transaction, est produit par un JdkDynamicAopProxy sur ma classe UserService.

Le dernier message de journal semble cependant alarmant. Il est invoqué à un point de jointure avant l'exécution de la méthode. Lorsque vous regardez la source pour AnnotationTransactionAspect, il génère ce message si aucun gestionnaire de transactions n'a été défini. Dans ce cas, parce que Spring n'effectue jamais aucune injection de dépendance sur cet aspect.

Il me semble que deux "styles" de transactions différents sont appliqués: le proxy dynamique, ET l'aspect. La seule configuration relative à une transaction que j'ai est:

<tx:annotation-driven transaction-manager="txManager" /> 

Nous utilisons AspectJ dans le projet, mais il n'y a aucun aspect de AnnotationTransactionAspect enregistré dans mon aop.xml. Nous utilisons Spring 3.0.2.RELEASE.

Devrais-je être alarmé par cela? Est-ce que Spring enregistre cet aspect pour moi? Ne devrais-je pas utiliser annotation-driven lorsque j'utilise AspectJ?

Répondre

8

étrange, il semble que vous avez cette configuration:

<tx:annotation-driven 
    transaction-manager="transactionManager" mode="aspectj" /> 

(support de transaction en utilisant AspectJ, non mandataires JDK)

Étant donné que votre config n'a pas un attribut de mode, la valeur par défaut devrait lancer en (mode proxy). Mais AnnotationTransactionAspect est l'aspect exact utilisé par le mode aspectj.

+1

Votre réponse a moi l'idée d'ajouter mode = "aspectj" pour voir comment cela fonctionnerait. Il semble que maintenant cela fonctionne comme prévu - il n'y a pas de proxy dynamique impliqué et l'aspect obtient le gestionnaire de transactions injecté. Intéressant. – waxwing

+0

Je pense que vous venez de me sauver un lot de douleur. Cela l'a arrangé pour moi et j'aurais fourré pour toujours si je n'avais pas trouvé cette réponse! –

+1

Juste couru dans cela aussi bien. Cette déclaration de log aurait été bien sur WARN à la place. Si vous utilisez Java Config, utilisez ceci: @EnableTransactionManagement (mode = AdviceMode.ASPECTJ) ' –

2

Pour obtenir des transactions aspectj fonctionnant avec java config.

@EnableWebMvc 
@Configuration 
@ComponentScan("com.yourdomain") 
@EnableTransactionManagement(mode=AdviceMode.ASPECTJ) 
public class ApplicationConfig extends WebMvcConfigurerAdapter { 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 

     //... 
    } 

    @Bean 
    public JpaTransactionManager transactionManager() { 

     JpaTransactionManager bean = new JpaTransactionManager(entityManagerFactory().getObject()); 
     return bean ; 
    } 

    @Bean 
    public AnnotationTransactionAspect annotationTransactionAspect() { 

     AnnotationTransactionAspect bean = AnnotationTransactionAspect.aspectOf(); 
     bean.setTransactionManager(transactionManager()); 
     return bean; 
    } 
} 

Si vous utilisez Maven:

<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>aspectj-maven-plugin</artifactId> 
    <version>1.7</version> 
    <configuration> 
     <aspectLibraries> 
      <aspectLibrary> 
       <groupId>org.springframework</groupId> 
       <artifactId>spring-aspects</artifactId> 
      </aspectLibrary> 
     </aspectLibraries> 
     <complianceLevel>1.8</complianceLevel> 
     <source>1.8</source> 
     <target>1.8</target> 
     <showWeaveInfo>true</showWeaveInfo> 
    </configuration> 
    <executions> 
     <execution> 
      <goals> 
       <goal>compile</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 

Si vous utilisez Eclipse, cela fera en sorte que le tissage est réalisé lors du déploiement de l'intérieur Eclipse:

http://www.eclipse.org/ajdt/