简体   繁体   English

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

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

I am in the process of adding Spring declarative transactions via the @Transactional annotation to an existing Java project. 我正在通过@Transactional注释将Spring声明性事务添加到现有Java项目中。

When I ran into a problem (unrelated to this question), I turned on full debug logging. 当我遇到问题(与此问题无关)时,我打开了完整的调试日志记录。 Curiously, I noticed the following: 奇怪的是,我注意到以下几点:

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

After some debugging, I found out that the first three log entries, where it says it found a thread-bound session and is using that transaction, is produced by a JdkDynamicAopProxy on my UserService class. 经过一些调试后,我发现前三个日志条目,它说它找到一个线程绑定会话并使用该事务,由我的UserService类上的JdkDynamicAopProxy生成。

The last log message looks alarming though. 最后一条日志消息看起来很惊人。 It is invoked at a joinpoint before the method execution. 它在方法执行之前在连接点调用。 When looking at the source for AnnotationTransactionAspect, it produces this message if no transaction manager has been set. 查看AnnotationTransactionAspect的源时,如果未设置事务管理器,则会生成此消息。 In this case, because Spring never performs any dependency injection on this aspect. 在这种情况下,因为Spring从不在这方面执行任何依赖注入。

It looks to me like two different "styles" of transactions are both applied: the dynamic proxy, AND the aspect. 在我看来,两种不同的“风格”交易都适用:动态代理和方面。 The only transaction-related configuration I have is: 我唯一与事务相关的配置是:

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

We are using AspectJ in the project, but there is no AnnotationTransactionAspect aspect registered in my aop.xml. 我们在项目中使用了AspectJ,但是在我的aop.xml中没有注册AnnotationTransactionAspect方面。 We are using Spring 3.0.2.RELEASE. 我们正在使用Spring 3.0.2.RELEASE。

Should I be alarmed by this? 我应该对此感到震惊吗? Does Spring register this aspect for me? Spring会为我注册这方面吗? Should I not use annotation-driven when using AspectJ? 使用AspectJ时我不应该使用annotation-driven吗?

Strange, it sounds like you have this configuration: 很奇怪,听起来你有这样的配置:

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

(Transaction support using AspectJ, not JDK proxies) (使用AspectJ的事务支持,而不是JDK代理)

Since your config doesn't have a mode attribute, the default should kick in (proxy mode). 由于您的配置没有mode属性,因此默认情况应该启动(代理模式)。 But AnnotationTransactionAspect is the exact aspect used by the aspectj mode. 但是AnnotationTransactionAspect是aspectj模式使用的确切方面。

To get aspectj transactions working with java config. 使用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;
    }
}

If you are using maven: 如果你使用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>

If you are using eclipse, this will ensure that the weaving is done when deploying inside eclipse: 如果您正在使用eclipse,这将确保在eclipse中部署时完成编织:

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

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

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