Public 带有@Transactional 调用私有方法的方法

Public method with @Transactional calling private method

我有几个关于@Transactional 注释的问题。如果我有一个类似于下面的实现:

@Transactional
public Interface ExampleRepo {
    SampleClass createRecord();
}


public class RepoImpl implements ExampleRepo {

   public SampleClass createRecord() {
       return saveRecord();
   }

   private saveRecord() {
       //Saving record to Database.
   }
}

如果在私有方法上调用@Transactional,事务回滚是否会被忽略,因为Spring?但是,如果用@Transactional 注释的public 方法调用了一个实际执行数据库操作的私有方法。

这个事务会被标记为回滚吗?

根据Spring Documentation

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies ( proxy-target-class="true") or the weaving-based aspect ( mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.

因此,我建议在方法 createRecord() 级别或 RepoImpl class 级别使用 @Transaction

该事务中事务范围内的所有代码 运行s。但是,当事务上下文已存在时,如果事务方法是 运行,则可以指定行为。

当一个没有@Transactional的方法在事务块中被调用时,父事务将继续存在于新方法中。它将使用来自父方法(带有@Transactional 的方法)的相同连接,并且在被调用方法(没有@Transactional 的方法)中引起的任何异常都将导致事务按照事务定义中的配置进行回滚。

由于这个机制是基于proxies,只有'external'个通过代理传入的方法调用会被拦截。这意味着 'self-invocation',即目标对象中调用目标对象的其他方法的方法,不会在 运行 时导致实际事务,即使调用的方法标记为 @Transactional.