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

发布于 2024-09-16 05:41:57 字数 1240 浏览 3 评论 0原文

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

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

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 时不应该使用注释驱动吗?

I am in the process of adding Spring declarative transactions via the @Transactional annotation to an existing Java project.

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.

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. In this case, because Spring never performs any dependency injection on this aspect.

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. We are using Spring 3.0.2.RELEASE.

Should I be alarmed by this? Does Spring register this aspect for me? Should I not use annotation-driven when using AspectJ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逐鹿 2024-09-23 05:41:57

奇怪的是,听起来您有这样的配置:(

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

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

由于您的配置没有模式属性,因此默认值应该启动(代理模式)。但AnnotationTransactionAspect 正是aspectj 模式使用的aspect。

Strange, it sounds like you have this configuration:

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

(Transaction support using AspectJ, not JDK proxies)

Since your config doesn't have a mode attribute, the default should kick in (proxy mode). But AnnotationTransactionAspect is the exact aspect used by the aspectj mode.

难理解 2024-09-23 05:41:57

使aspectj事务与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;
    }
}

如果您使用的是 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/

To get aspectj transactions working with 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;
    }
}

If you are using 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:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文