【问题标题】:How Spring annotation Transactional internally works? [duplicate]Spring 注解 Transactional 内部如何工作? [复制]
【发布时间】:2020-09-10 03:18:29
【问题描述】:

我正在测试一些代码,发现了一个有趣的场景。

场景:

public class ServiceA {
        public List<Object> saveAndGetAllV1() {
            serviceB.saveAll();
            return getAll();
        }

        public List<Object> saveAndGetAllV2() {
            serviceB.saveAll();
            return serviceB.getAll();
        }

        @Transactional(propagation = Propagation.MANDATORY)
        public List<Object> getAll() {
            repository.findAll();
        }
    }

    public class ServiceB {
        public void saveAll() {
            serviceC.saveAll();
        }

        public List<Object> getAll() {
            return repository.findAll();
        }
    }

    public class ServiceC {

        public void saveAll() {
            repository.saveAll(object);
        }

        @Transactional(propagation = Propagation.MANDATORY)
        public List<Object> getAll() {
            return repository.findAll();
        }
    }

即使在serviceA.getAll() 方法中事务是强制性的,saveAndGetAllV1() 方法也不会给出任何错误。而另一方面,saveAndGetAllV2() 给出错误,因为serviceC.getAll() 需要强制事务。

所以我的问题是为什么在serviceA.getAll() 方法中事务是自动创建的,而在serviceC.getAll() 方法中事务不是自动创建的?

【问题讨论】:

  • Spring 使用代理,只有方法调用 INTO 代理才会被拦截并应用方面。您的第一个是在内部方法调用中,因此不通过代理,基本上被忽略了。
  • @M.Deinum 好的。但是有什么优雅的方法可以找出所有那些 @Transactional 注释没用的方法。就像serviceA.getAll() 方法上的那个一样。

标签: spring hibernate spring-boot jpa spring-data-jpa


【解决方案1】:

方法 saveAndGetAllV1() 不会给出任何错误,即使当 在 serviceA.getAll() 方法中事务是强制的。

那是因为getAll()的调用是本地调用,然后@Transactional没有被使用,因为本地调用没有使用代理。

【讨论】:

  • 所以即使我只用@Transactional 添加serviceA.getAll() 也没有任何意义,因为它只会在findAll 方法级别创建事务。对吗?
  • 对。您需要注释 saveAndGetAllV1
猜你喜欢
  • 2017-01-07
  • 2011-04-06
  • 2023-03-25
  • 2019-02-18
  • 2014-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-11
相关资源
最近更新 更多