繁体   English   中英

@Transactional 方法调用另一个没有@Transactional 注释的方法?

[英]@Transactional method calling another method without @Transactional anotation?

我在服务 class 中看到了一个方法,它被标记为@Transactional ,但它也在同一个 class 中调用了一些其他方法,这些方法没有被标记为@Transactional

这是否意味着对单独方法的调用导致应用程序打开与数据库的单独连接或暂停父事务等?

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

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

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

您可以在spring 事务文档声明性事务管理部分找到更多详细信息。

Spring 声明性事务 model 使用 AOP 代理。 所以 AOP 代理负责创建事务。 仅当从实例外部调用实例中的方法时,AOP 代理才会处于活动状态。

  • 这是否意味着对单独方法的调用导致应用程序打开与数据库的单独连接或暂停父事务等?

这取决于传播水平 以下是所有可能的级别

例如,如果传播级别是NESTED ,则当前事务将“暂停”并创建新事务(注意:嵌套事务的实际创建仅适用于特定事务管理器

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

默认传播级别(您称之为“行为”)是REQUIRED 如果调用了带有@Transactional注释的“内部”方法(或通过 XML 以声明方式进行事务处理),它将在同一个事务中执行,例如“没有新内容”被创建。

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

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

如果内部方法没有使用@Transactional 注解,内部方法将影响外部方法。

如果内部方法也使用带有REQUIRES_NEW的 @Transactional 注释,则会发生以下情况。

...
@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_NEW进行注释并引发 RuntimeException,因此它将其事务设置为回滚,但不会影响外部事务。 外部事务在内部事务开始时暂停,然后在内部事务结束后恢复。 它们彼此独立运行,因此外部事务可以成功提交。

暂无
暂无

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

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