@Controller、@Service、@Repository beans 在@EnableTransactionManagement 模式下失败 = AdviceMode.PROXY 或默认失败
@Controller, @Service, @Repository beans fails on @EnableTransactionManagement in mode = AdviceMode.PROXY or default fails
为什么在默认模式或 PROXY 模式下使用 @EnableTransactionManagement 会尝试像 @Controller、@Service 这样的 beans 创建,以及 @Repositories。我不会丢弃另一种针对这种不良行为的bean。
我有一个项目:
- SpringBoot 2.1.8.RELEASE + JPA + Rest Controller
- PostgreSQL 9.6
- @Transactional 对 save、update 和 删除(也就是批量删除)
它创建代理 类 并清空 ApplicationContext 中剩余的 bean。
默认模式为PROXY。当设置 ASPECTJ 建议模式时,所有 bean 都被注入到正确的位置。 Check Spring current docs on the subject.
The mode()
attribute controls how advice is applied: If the mode is AdviceMode.PROXY
(the default), then the other attributes control the behavior of the proxying. Please note that proxy mode allows for interception of calls through the proxy only; local calls within the same class cannot get intercepted that way.
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.
像这样:
@Transactional 方法仍然失败。由于“TransactionRequiredException”,所以ASPECTJ并没有解决持久层的问题,只是授予bean注入(可能没有创建平台事务管理器)。接下来做什么?
查看交易异常:
!!!解法:
处理事务时,范围必须在 beans 链中共享:@Service(也称为调用方方法)<-@Repository(也称为事务方法),@Service 上下文(class,方法)应标记为@Transactional。适用于以事务操作结束的调用堆栈中带注释的方法或 classes(自下而上 方法)。
注释序列:
- @EnableTransactionManagement(在@Configuration 中类似 classes 或 @SpringBootApplication -autoconfiguration-)
- @Transactional 在 bean 注入链中注释 method/classes(自下而上:持久化method/class,然后是@Service/@Component层)
- @Autowired bean 候选注释(Service instance in @Controller class, 存储库实例 @Service class)
注意: Spring AOP 不会从基于功能接口的特性中创建 proxy 属性,仅推荐对象实例使用封装持久性逻辑的方法。
例如
Function<T, R> function
BiFunction<T1,T2,R> function
Supplier<T> supplier
...
为什么在默认模式或 PROXY 模式下使用 @EnableTransactionManagement 会尝试像 @Controller、@Service 这样的 beans 创建,以及 @Repositories。我不会丢弃另一种针对这种不良行为的bean。
我有一个项目:
- SpringBoot 2.1.8.RELEASE + JPA + Rest Controller
- PostgreSQL 9.6
- @Transactional 对 save、update 和 删除(也就是批量删除)
它创建代理 类 并清空 ApplicationContext 中剩余的 bean。
默认模式为PROXY。当设置 ASPECTJ 建议模式时,所有 bean 都被注入到正确的位置。 Check Spring current docs on the subject.
The
mode()
attribute controls how advice is applied: If the mode isAdviceMode.PROXY
(the default), then the other attributes control the behavior of the proxying. Please note that proxy mode allows for interception of calls through the proxy only; local calls within the same class cannot get intercepted that way.Note that if the
mode()
is set toAdviceMode.ASPECTJ
, then the value of theproxyTargetClass()
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.
像这样:
@Transactional 方法仍然失败。由于“TransactionRequiredException”,所以ASPECTJ并没有解决持久层的问题,只是授予bean注入(可能没有创建平台事务管理器)。接下来做什么?
查看交易异常:
!!!解法:
处理事务时,范围必须在 beans 链中共享:@Service(也称为调用方方法)<-@Repository(也称为事务方法),@Service 上下文(class,方法)应标记为@Transactional。适用于以事务操作结束的调用堆栈中带注释的方法或 classes(自下而上 方法)。
注释序列:
- @EnableTransactionManagement(在@Configuration 中类似 classes 或 @SpringBootApplication -autoconfiguration-)
- @Transactional 在 bean 注入链中注释 method/classes(自下而上:持久化method/class,然后是@Service/@Component层)
- @Autowired bean 候选注释(Service instance in @Controller class, 存储库实例 @Service class)
注意: Spring AOP 不会从基于功能接口的特性中创建 proxy 属性,仅推荐对象实例使用封装持久性逻辑的方法。
例如
Function<T, R> function
BiFunction<T1,T2,R> function
Supplier<T> supplier
...