繁体   English   中英

Spring @Transactional既作为动态Jdk代理又作为aspectj方面应用

[英]Spring @Transactional is applied both as a dynamic Jdk proxy and an aspectj aspect

我正在通过@Transactional注释将Spring声明性事务添加到现有Java项目中。

当我遇到问题(与此问题无关)时,我打开了完整的调试日志记录。 奇怪的是,我注意到以下几点:

17:47:27,834 DEBUG HibernateTransactionManager:437 - Found thread-bound Session [org.hibernate.impl.SessionImpl@10ed8a8e] 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

经过一些调试后,我发现前三个日志条目,它说它找到一个线程绑定会话并使用该事务,由我的UserService类上的JdkDynamicAopProxy生成。

最后一条日志消息看起来很惊人。 它在方法执行之前在连接点调用。 查看AnnotationTransactionAspect的源时,如果未设置事务管理器,则会生成此消息。 在这种情况下,因为Spring从不在这方面执行任何依赖注入。

在我看来,两种不同的“风格”交易都适用:动态代理和方面。 我唯一与事务相关的配置是:

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

我们在项目中使用了AspectJ,但是在我的aop.xml中没有注册AnnotationTransactionAspect方面。 我们正在使用Spring 3.0.2.RELEASE。

我应该对此感到震惊吗? Spring会为我注册这方面吗? 使用AspectJ时我不应该使用annotation-driven吗?

很奇怪,听起来你有这样的配置:

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

(使用AspectJ的事务支持,而不是JDK代理)

由于您的配置没有mode属性,因此默认情况应该启动(代理模式)。 但是AnnotationTransactionAspect是aspectj模式使用的确切方面。

使用java配置获取aspectj事务。

@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;
    }
}

如果你使用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>

如果您正在使用eclipse,这将确保在eclipse中部署时完成编织:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM