@ Controller,@ Service,@ Repository Bean在模式= AdviceMode.PROXY上的@EnableTransactionManagement上失败,或者默认失败

菲利克斯·阿巴利(Felix Aballi):

为什么使用@EnableTransactionManagement在默认模式下或对豆类创造像代理模式的尝试@Controller@Service@Repositories我不会丢弃针对这种不良行为的另一种豆子。

我有一个项目

  • SpringBoot 2.1.8.RELEASE + JPA + Rest控制器
  • PostgreSQL 9.6
  • @Transactional注释,如 save update delete(也可以批量删除)

它创建代理类,并使ApplicationContext中的其余bean为空。

EnableTransactionManagement默认/代理建议模式

菲利克斯·阿巴利(Felix Aballi):

默认模式是PROXYAspectJ的设置咨询模式,所有的豆类都是在正确的地方注射。查看关于该主题的Spring最新文档

mode()属性控制建议的应用方式:如果模式为AdviceMode.PROXY(默认),则其他属性控制代理的行为。请注意,代理模式仅允许通过代理拦截呼叫;同一类中的本地调用无法以这种方式被拦截。

Note that if the mode() is set to AdviceMode.ASPECTJ, then the value of the proxyTargetClass() attribute will be ignored. Note also that in this case the spring-aspects module JAR must be present on the classpath, with compile-time weaving or load-time weaving applying the aspect to the affected classes. There is no proxy involved in such a scenario; local calls will be intercepted as well.

Like this:

EnableTransactionManagement ASPECTJ建议模式

Still, @Transactional methods fail. Due to "TransactionRequiredException", so ASPECTJ does not solve the problem in persistence layer, only grants beans injection (maybe no platform transaction manager is created). What to do next?

See the transaction exception:

交易例外

!!! Solution:

When working with transactions, the scope has to be shared in the beans chain: @Service(also, caller method)<-@Repository(also, transactional method), @Service context (class, method) shall be marked as @Transactional. Applies to annotated methods or classes in the call stack that ends in transactional operation (bottom-up approach).

Annotation sequence:

  1. @EnableTransactionManagement (in @Configuration alike classes or @SpringBootApplication -autoconfiguration-)
  2. @Transactional annotated method/classes in beans injection chain (bottom-up: persistent method/class, then @Service/@Component layers)
  3. Bean候选者上的 @Autowired注释(@Controller类中的 Service实例,@ Service类中的 Repository实例

注意: Spring AOP不会从基于功能接口的功能创建代理属性,因此仅推荐使用封装持久性逻辑的方法的对象实例。

例如

Function<T, R> function 
BiFunction<T1,T2,R> function 
Supplier<T> supplier
... 

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章