Java @事务性方法调用另一个没有@Transactional anotation的方法?

Java @事务性方法调用另一个没有@Transactional anotation的方法?,java,spring,spring-transactions,transactional,Java,Spring,Spring Transactions,Transactional,我在服务类中见过一个标记为@Transactional的方法,但它也在调用同一类中未标记为@Transactional的其他方法 这是否意味着对分离方法的调用会导致应用程序打开到DB的分离连接或挂起父事务等 没有任何注释的方法被另一个带有@Transactional注释的方法调用时的默认行为是什么?当您在事务块内调用一个没有@Transactional的方法时,父事务将继续使用新方法。它将使用来自父方法(使用@Transactional)的相同连接,并且在被调用方法(不使用@Transactio

我在服务类中见过一个标记为
@Transactional
的方法,但它也在调用同一类中未标记为
@Transactional
的其他方法

这是否意味着对分离方法的调用会导致应用程序打开到DB的分离连接或挂起父事务等


没有任何注释的方法被另一个带有
@Transactional
注释的方法调用时的默认行为是什么?

当您在事务块内调用一个没有
@Transactional
的方法时,父事务将继续使用新方法。它将使用来自父方法(使用
@Transactional
)的相同连接,并且在被调用方法(不使用
@Transactional
)中导致的任何异常都将导致事务回滚,如事务定义中配置的那样

如果在同一实例中从具有
@Transactional
的方法调用具有
@Transactional
注释的方法,则被调用的方法事务行为将不会对事务产生任何影响。但是,如果您从另一个具有事务定义的方法调用具有事务定义的方法,并且它们处于不同的实例中,那么被调用方法中的代码将遵循被调用方法中给出的事务定义

您可以在的声明性事务管理一节中找到更多详细信息


Spring声明性事务模型使用AOP代理。因此,AOP代理负责创建事务。只有从实例外部调用实例中的方法时,AOP代理才会处于活动状态。

@Transactional标记事务边界(开始/结束),但事务本身绑定到线程。一旦事务启动,它就会在方法调用之间传播,直到原始方法返回,事务提交/回滚

如果调用另一个具有@Transactional注释的方法,则传播取决于该注释的传播属性。

  • 这是否意味着对分离方法的调用会导致应用程序打开到DB的分离连接或挂起父事务等
那要看具体情况。以下是所有可能的级别

例如,在传播级别为的情况下,当前事务将“挂起”,并将创建一个新事务(注意:嵌套事务的实际创建仅适用于特定的事务管理器)

  • 没有任何注释的方法的默认行为是什么?另一个使用@Transactional annotation的方法调用了该方法

默认传播级别(您称之为“行为”)为。如果调用的“内部”方法上有
@Transactional
注释(或通过XML进行声明性事务处理),则它将在相同的事务中执行,例如创建“nothing new”。

如果内部方法没有用@Transactional注释,则内部方法将影响外部方法

如果内部方法也用@Transactional with
REQUIRES\u NEW
注释,则会发生以下情况

...
@Autowired
private TestDAO testDAO;

@Autowired
private SomeBean someBean;

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void outerMethod(User user) {
  testDAO.insertUser(user);
  try{
    someBean.innerMethod();
  } catch(RuntimeException e){
    // handle exception
  }
}


@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void innerMethod() {
  throw new RuntimeException("Rollback this transaction!");
}

内部方法用
REQUIRES\u NEW
注释,并引发RuntimeException,因此它将其事务设置为回滚,但不会影响外部事务。外部事务在内部事务开始时暂停,然后在内部事务结束后恢复。它们彼此独立运行,因此外部事务可以成功提交。

这是spring的默认行为吗?是的。这是默认行为。@Tomasz Yes。但是还应该提到的是,在从另一个@Transactional方法调用的方法上更改事务传播不会产生任何效果。@Tomasz,这就是我所说的
将遵循被调用方法中给出的事务定义。但是,如果调用来自同一个对象实例,则不会产生任何效果,因为调用不会通过负责事务维护的aop代理进行传播。@Filip,这不完全正确,如果您从不同的对象/实例调用具有
@Transactional
定义的方法,则即使调用方法具有不同的
@Transactional
属性,被调用的方法也将遵循其自己的事务定义。不支持且没有任何注释的子类如何?它是否继承不受支持的事务,或者他们是否按照默认要求打开了新事务?例如:f1.call(){f2()}带有f1不支持的注释和f2不支持的注释。这3个答案在某种程度上相互冲突,不确定哪一个更准确。@EricWang只想分享我今天测试了这个场景,答案是(带注释)对于这种内部调用场景,innerMethod()是最准确的。为了向初学者澄清,我非常确定innerMethod()需要位于与outerMethod()不同的bean(也称为Spring托管java对象)上。如果它们都在同一个bean上,我认为innerMethod实际上不会使用其注释中声明的事务行为。相反,它将使用outerMethod()声明中声明的内容。这是因为Spring处理AOP的方式,AOP用于它的@Transactional注释()