一尘不染

Spring @Transactional属性可以在私有方法上工作吗?

spring

如果我在Spring bean的私有方法上有一个@Transactional -annotation,该注释有什么作用吗?

如果@Transactional注释位于公共方法上,则它将起作用并打开一个事务。

public class Bean {
  public void doStuff() {
     doPrivateStuff();
  }
  @Transactional
  private void doPrivateStuff() {

  }
}

...

Bean bean = (Bean)appContext.getBean("bean");
bean.doStuff();

阅读 2407

收藏
2020-04-11

共2个答案

一尘不染

问题不是私有的还是公共的,问题是:如何调用它以及你使用哪种AOP实现!

如果你使用(默认)Spring Proxy AOP,则@Transational仅当调用通过代理时,才会考虑Spring提供的所有AOP功能(如)。-如果从另一个 bean 调用带注释的方法,通常就是这种情况。

这有两个含义:

  • 因为不能从另一个bean调用私有方法(例外是反射),@Transactional所以不考虑其注释。
  • 如果该方法是公共方法,但是从同一个bean调用,则也不会考虑该方法(仅当使用(默认)Spring Proxy AOP时,此语句才是正确的)。

恕我直言,你应该使用AspectJ模式而不是Spring Proxies来解决问题。而且AspectJ事务性方面甚至被编织成私有方法(已在Spring 3.0中进行了检查)。

2020-04-11
一尘不染

你的问题的答案是否定的- @Transactional如果用于注释私有方法,则将无效。代理生成器将忽略它们。

在Spring手册10.5.6章中有记录:

方法可见性和 @Transactional

使用代理时,应仅将@Transactional注释应用于具有公共可见性的方法。如果使用注释对受保护的,私有的或程序包可见的方法进行 @Transactional注释,则不会引发任何错误,但是带注释的方法不会显示已配置的事务设置。如果需要注释非公共方法,请考虑使用AspectJ(请参见下文)。

2020-04-11