繁体   English   中英

Spring boot r2dbc transactional:注释哪个方法

[英]Spring boot r2dbc transactional: which method to annotate

我正在使用带有 webflux 的 spring-boot 2.4.2 连接到 postgres 数据库。 我在使用@Transactional时观察到一种我不理解的行为。

为了展示这种行为,我创建了一个示例应用程序,它尝试将行添加到两个表中; 表“a”和表“b”。 对表“a”的插入预计会因重复键违规而失败。 鉴于使用了事务性,我希望不会将任何行添加到表“b”中。

但是,根据我使用@Transactional注释的方法,我会得到不同的结果。

如果我注释 controller 方法,事情会按预期工作,并且不会向表 B 添加任何行。

    @PostMapping("/")
    @Transactional
    public Mono<Void> postEntities() {
        return demoService.doSomething();
    }

DemoService 看起来像这样:

    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);
    }

如果我将@Transactional注释从 controller 移动到doSomething() ,那么事务仍然按预期工作。 但是,如果我将@Transactional注释移动到internal() ,则事务不会按预期工作。 一行被添加到表“b”。

这个例子的完整代码在这里: https://github.com/alampada/pg-spring-r2dbc-transactional

我不明白为什么将注释移动到internal()方法会导致事务处理出现问题。 你能解释一下吗?

来自 Spring 参考文档: 使用@Transactional

在代理模式下(默认),只有通过代理传入的外部方法调用会被拦截。 这意味着自调用(实际上,目标 object 中的一个方法调用目标对象的另一个方法)在运行时不会导致实际事务,即使调用的方法标有 @Transactional。 此外,代理必须完全初始化以提供预期的行为,因此您不应在初始化代码(即@PostConstruct)中依赖此功能。

这里从 doSomething() 到 internal() 的调用是自调用。

请注意,Spring 框架的声明式事务支持是通过 AOP 代理启用的。

Spring 参考文档: 了解 AOP 代理将清楚说明为什么自调用在代理上不起作用。 请通读从这里开始的部分,这里要理解的关键是 main(..) 中的客户端代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM