2010-08-26 6 views
5

Sono in procinto di aggiungere transazioni dichiarative di Spring tramite l'annotazione @Transactional a un progetto Java esistente.Spring @Transactional viene applicato sia come proxy dinamico Jdk che aspetto aspetto

Quando ho avuto un problema (non correlato a questa domanda), ho attivato la registrazione completa del debug. Curiosamente, ho notato quanto segue:

 
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 

Dopo un po 'di debug, ho scoperto che le prime tre voci di registro, dove si dice che ha trovato una sessione di filo-bound e sta usando tale operazione, è prodotto da un JdkDynamicAopProxy su la mia classe UserService.

L'ultimo messaggio di registro sembra allarmante. Viene richiamato in un joinpoint prima dell'esecuzione del metodo. Quando si guarda all'origine di AnnotationTransactionAspect, questo messaggio viene generato se non è stato impostato alcun gestore transazioni. In questo caso, poiché Spring non esegue mai alcuna iniezione di dipendenza su questo aspetto.

Mi sembra che vengano applicati due diversi "stili" di transazioni: il proxy dinamico E l'aspetto. L'unica configurazione di transazione legati che ho è:

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

Stiamo utilizzando AspectJ nel progetto, ma non v'è nessun aspetto AnnotationTransactionAspect registrato nel mio aop.xml. Stiamo usando Spring 3.0.2.RELEASE.

Devo essere allarmato da questo? Spring registra questo aspetto per me? Non dovrei usare annotation-driven quando uso AspectJ?

risposta

8

Strano, sembra che tu hai questa configurazione:

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

(supporto delle transazioni utilizzando AspectJ, non deleghe JDK)

Dal momento che la configurazione non ha un attributo di modalità, il default dovrebbe calci in (modalità proxy). Ma AnnotationTransactionAspect è l'esatto aspetto usato dalla modalità aspectj.

+1

La tua risposta ha dato a me l'idea di aggiungere mode = "aspectj" per vedere come funzionerebbe. Sembra che ora funzioni come previsto - non è coinvolto alcun proxy dinamico e l'aspetto viene iniettato dal gestore transazioni. Interessante. – waxwing

+0

Penso che tu mi abbia appena salvato una pena di dolore. Questo lo ha risolto per me e io avrei cercato in giro per sempre se non avessi trovato questa risposta! –

+1

Ci siamo imbattuti anche in questo. Quella dichiarazione di registro sarebbe stata invece eccezionale su WARN. Se si utilizza Java Config, utilizzare questo: '@EnableTransactionManagement (mode = AdviceMode.ASPECTJ)' –

2

Per ottenere le operazioni con le operazioni con 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; 
    } 
} 

Se si utilizza 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> 

Se si utilizza Eclipse, questo farà sì che la tessitura è fatto durante la distribuzione all'interno di Eclipse:

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