ant*_*wrx 7 spring-boot spring-data-r2dbc r2dbc r2dbc-postgresql
我使用 spring-boot 2.4.2 和 webflux 连接到 postgres 数据库。@Transactional我在使用时观察到一种我不明白的行为。
为了展示该行为,我创建了一个示例应用程序,尝试将行添加到两个表中;表“a”和表“b”。对表“a”的插入预计会因重复键冲突而失败。鉴于使用了事务性,我预计不会将任何行添加到表“b”中。
但是,根据我使用的注释方法,@Transactional我会得到不同的结果。
如果我注释控制器方法,一切都会按预期工作,并且不会向表 B 添加任何行。
@PostMapping("/")
@Transactional
public Mono<Void> postEntities() {
return demoService.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
演示服务如下所示:
public Mono<Void> doSomething() {
return internal();
}
public Mono<Void> internal() {
Mono<EntityA> clash = Mono.just(EntityA.builder().name("clash").build()).flatMap(repositoryA::save);
Mono<EntityB> ok = Mono.just(EntityB.builder().name("ok").build()).flatMap(repositoryB::save);
return ok.and(clash);
}
Run Code Online (Sandbox Code Playgroud)
如果我将@Transactional注释从控制器移至doSomething(),那么事务仍然按预期工作。但是,如果我将@Transactional注释移至internal(),则事务将无法按预期工作。一行被添加到表“b”中。
此示例的完整代码在这里:https ://github.com/alampada/pg-spring-r2dbc-transactional
我不明白为什么将注释移至internal()方法会导致事务处理出现问题。您能解释一下吗?
来自Spring参考文档:使用@Transactional
\n\n\n在代理模式(默认)下,仅拦截通过代理传入的外部方法调用。这意味着自调用(实际上,目标对象中的方法调用目标对象的其他方法)不会在运行时导致实际的事务,即使调用的方法标有@Transactional。此外,必须完全初始化代理才能提供预期的行为,因此您不应在初始化代码(即 @PostConstruct)中依赖此功能。
\n
这里从doSomething()到internal()的调用是一个自调用。
\n请注意,Spring Framework\xe2\x80\x99s 声明性事务支持是通过 AOP 代理启用的。
\nSpring 参考文档:了解 AOP 代理将清楚地说明为什么自调用在代理上不起作用。请通读以\n 开头的部分,这里要理解的关键是 main(..) 中的客户端代码
\n| 归档时间: |
|
| 查看次数: |
3140 次 |
| 最近记录: |