java @EnableTransactionManagement 的范围是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25990741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 09:06:15  来源:igfitidea点击:

What is the scope of @EnableTransactionManagement?

javaspringjpaspring-transactions

提问by Vadym S. Khondar

I'm trying to understand where is the right place to put @EnableTransactionManagementannotation in case of multiple JavaConfig contexts?

我试图了解在@EnableTransactionManagement多个 JavaConfig 上下文的情况下在哪里放置注释的正确位置?

Consider following scenario: I have JPA config in JPAConfig.java and AppConfig.java with set of service beans. Then I compose overall application config in RootConfig.java.

考虑以下场景:我在 JPAConfig.java 和 AppConfig.java 中有 JPA 配置和一组服务 bean。然后我在 RootConfig.java 中编写整个应用程序配置。

I define transaction manager within JPAConfig.java as well as enable scanning for JPA repositories - as those expose transactional behavior, I put @EnableTransactionManagementover JPAConfig and it works.

我在 JPAConfig.java 中定义了事务管理器,并启用了对 JPA 存储库的扫描——因为那些暴露了事务行为,我把@EnableTransactionManagementJPAConfig放在了上面并且它可以工作。

However, some of service beans also need to have transactional methods e.g. accessing several repositories within single transaction. Should I also put @EnableTransactionManagementover AppConfig as well? Looking into implementation of this annotation is seems to me that such approach would cause redefinition of some beans. And actually doing so doesn't seem to work for me.

但是,一些服务 bean 还需要具有事务方法,例如在单个事务中访问多个存储库。我也应该把@EnableTransactionManagementAppConfig放在一边吗?在我看来,查看此注释的实现,这种方法会导致某些 bean 的重新定义。实际上这样做似乎对我不起作用。

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("com.mypackage.repositories")
public class JPAConfig {
 // ... here are EntityManager and PlatformTransactionManager beans
}


@Configuration
@ComponentScan("com.mypackage.services")
// @EnableTransactionManagement // - ???
public class AppConfig {
}

@Configuration
@Import({AppConfig.class, JPAConfig.class})
public class RootConfig {
}

Appreciate any advices.

感谢任何建议。

回答by Vadym S. Khondar

After some experiments I seem to have found the answer myself:

经过一些实验,我似乎自己找到了答案:

  • There is no need to configure @EnableTransactionManagementon each piece of context configuration although it does matter how early this annotation is discovered as it registers internalTransactionAdvisorwhich actually processes @Transactionalannotations on created beans.
  • In my case, I changed the order of contexts in @Importdeclaration so that PersistenceConfigthat holds @EnableTransactionManagementis the first. After this beans from other pieces can use AOP declarative transaction.
  • Another caveat relates to simultaneous use of @EnableTransactionManagementand @EnableGlobalMethodSecurity. Global method security uses bean post processing which seems to require whole security configuration to be wired. BeanPostProcessors are created early on context start-up so you can't use declarative @Transactionalin any bean that would be needed to bootstrap spring security (in my case UserDetailsContextMapper) - advisor is not yet created then!
  • 无需@EnableTransactionManagement在每个上下文配置上进行配置,尽管此注释被发现的时间很早很重要,因为它注册internalTransactionAdvisor了实际处理已@Transactional创建 bean 上的注释。
  • 就我而言,我改变了上下文的顺序@Import声明,使PersistenceConfig持有@EnableTransactionManagement是第一。之后这个bean从其他部分可以使用AOP声明性事务。
  • 另一个警告涉及同时使用@EnableTransactionManagement@EnableGlobalMethodSecurity。全局方法安全使用 bean 后处理,这似乎需要连接整个安全配置。BeanPostProcessors 是在上下文启动的早期创建的,因此您不能@Transactional在引导 spring 安全性(在我的情况下UserDetailsContextMapper)所需的任何 bean 中使用声明性- 那时还没有创建顾问程序!