2010-08-26 19 views
5

Estoy en el proceso de agregar transacciones declarativas de Spring a través de la anotación @Transactional a un proyecto Java existente.Spring @Transactional se aplica como un proxy Jdk dinámico y un aspecto aspectj

Cuando me encontré con un problema (no relacionado con esta pregunta), activé el registro de depuración completo. Curiosamente, me di cuenta de lo siguiente:

 
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 

Después de una cierta depuración, descubrí que las tres primeras entradas del registro, donde dice que encontró una sesión de hilo de ruedas y utiliza esa transacción, se produce por un JdkDynamicAopProxy en mi clase UserService.

El último mensaje de registro parece alarmante. Se invoca en un punto de unión antes de la ejecución del método. Al buscar en el origen de AnnotationTransactionAspect, este mensaje aparece si no se ha establecido ningún administrador de transacciones. En este caso, porque Spring nunca realiza ninguna inyección de dependencia en este aspecto.

Me parece que se aplican dos "estilos" diferentes de transacciones: el proxy dinámico Y el aspecto. La única configuración relacionada con las transacciones que tengo es:

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

Estamos utilizando AspectJ en el proyecto, pero no hay ningún aspecto AnnotationTransactionAspect registrada en mi aop.xml. Estamos usando Spring 3.0.2.RELEASE.

¿Debería alarmarme por esto? ¿Spring registra este aspecto para mí? ¿No debería usar annotation-driven cuando uso AspectJ?

Respuesta

8

extraño, parece que tiene esta configuración:

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

(Soporte de transacciones utilizando AspectJ, no proxies JDK)

Debido a que su configuración no tiene un atributo modo, el valor por defecto debería patear en (modo proxy). Pero AnnotationTransactionAspect es el aspecto exacto utilizado por el modo aspectj.

+1

Su respuesta dio Me la idea de agregar mode = "aspectj" para ver cómo funcionaría. Parece como si ahora funciona como se esperaba: no hay un proxy dinámico involucrado y el aspecto obtiene el administrador de transacciones inyectado. Interesante. – waxwing

+0

Creo que me salvaste un poco de dolor. ¡Eso lo solucionó para mí y hubiera hurgado por siempre si no hubiera encontrado esta respuesta! –

+1

Acabo de toparme con esto también. Esa declaración de registro habría sido genial en WARN en su lugar. Si usa Java Config, use esto: '@EnableTransactionManagement (mode = AdviceMode.ASPECTJ)' –

2

Para obtener transacciones aspectoj trabajando con configuración java.

@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 está utilizando 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 está utilizando Eclipse, esto asegurará que el tejido se realiza cuando se despliega dentro de Eclipse:

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

Cuestiones relacionadas