@Transactional 方法在没有 @Transactional 注解的情况下调用另一个方法?

发布于 2024-11-11 06:42:00 字数 216 浏览 1 评论 0原文

我在 Service 类中看到了一个标记为 @Transactional 的方法,但它还调用了同一类中未标记为 @Transactional 的其他一些方法。

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

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

I've seen a method in a Service class that was marked as @Transactional, but it was also calling some other methods in that same class which were not marked as @Transactional.

Does it mean that the call to separate methods are causing the application to open separate connections to DB or suspend the parent transaction, etc?

What's the default behavior for a method without any annotations which is called by another method with @Transactional annotation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

像极了他 2024-11-18 06:42:00

当您在事务块内调用没有 @Transactional 的方法时,父事务将传播到新方法。它将使用来自父方法的相同连接(带 @Transactional),并且在被调用方法(不带 @Transactional)中引起的任何异常都将导致事务按配置回滚在交易定义中。

如果您从属于同一个 Spring Bean 的带有 @Transactional 的方法调用带有 @Transactional 注解的方法,那么被调用方法的事务行为不会对该方法产生任何影响。交易。但是,如果您从另一个具有事务定义的方法调用一个具有事务定义的方法,并且它们属于不同的 Spring Bean,那么被调用方法中的代码将遵循其自己的事务定义。

您可以在 Spring 事务管理文档

Spring声明式事务模型使用AOP代理,因此AOP代理负责事务的创建。仅当被调用方法属于与调用方不同的 Spring Bean 时,AOP 代理才会处于活动状态。

When you call a method without @Transactional within a transaction block, the parent transaction will propagate to the new method. It will use the same connection from the parent method (with @Transactional) and any exception caused in the called method (without @Transactional) will cause the transaction to rollback as configured in the transaction definition.

If you call a method with a @Transactional annotation from a method with @Transactional belonging to the same Spring Bean, then the called method's transactional behavior will not have any impact on the transaction. But if you call a method with a transaction definition from another method with a transaction definition, and they belong to different Spring Beans, then the code in the called method will follow its own transaction definitions.

You can find more details in the section Declarative transaction management of Spring Transaction Management documentation.

Spring declarative transaction model uses an AOP proxy, so the AOP proxy is responsible for the creation of the transactions. The AOP proxy will be active only if the called method belongs to a different Spring Bean than the caller one.

微凉徒眸意 2024-11-18 06:42:00
  • 这是否意味着对单独方法的调用会导致应用程序打开与数据库的单独连接或挂起父事务等?

这取决于 传播级别。以下是所有可能的级别 价值观

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

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

默认的传播级别(您所说的“行为”)是 必需。如果调用带有 @Transactional 注释的“内部”方法(或通过 XML 进行声明式事务),它将在同一事务中执行,例如“无新的”被创建。

  • Does that mean the call to separate methods are causing the application to open separate connections to DB or suspend the parent transaction, etc?

That depends on a propagation level. Here are all the possible level values.

For example in case a propagation level is NESTED a current transaction will "suspend" and a new transaction will be created ( note: actual creation of a nested transaction will only work on specific transaction managers )

  • What's the default behavior for a method without any annotations that is called by another method with @Transactional annotation?

The default propagation level ( what you call "behavior" ) is REQUIRED. In case an "inner" method is called that has a @Transactional annotation on it ( or transacted declaratively via XML ), it will execute within the same transaction, e.g. "nothing new" is created.

诗酒趁年少 2024-11-18 06:42:00

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

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

@Transactional marks the transaction boundary (begin/end), but the transaction itself is bound to the thread. Once a transaction starts, it propagates across method calls until the original method returns and the transaction commits/rolls back.

If another method is called that has a @Transactional annotation, then the propagation depends on the propagation attribute of that annotation.

饮湿 2024-11-18 06:42:00

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

如果内部方法也使用 @TransactionalPropagation.REQUIRES_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_NEW 注释并抛出 RuntimeException,因此它将设置其事务回滚,但不会影响外部事务。当内部事务开始时,外部事务暂停,然后在内部事务结束后恢复。它们彼此独立运行,因此外部事务可能会成功提交。

The inner method will affect the outer method if the inner method is not annotated with @Transactional.

In case the inner method is also annotated with @Transactional with Propagation.REQUIRES_NEW, the following will happen.

...
@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!");
}

The inner method is annotated with REQUIRES_NEW and throws a RuntimeException, so it will set its transaction to rollback but WILL NOT EFFECT the outer transaction. The outer transaction is PAUSED when the inner transaction starts and then RESUMES AFTER the inner transaction is concluded. They run independently of each other, so the outer transaction MAY commit successfully.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文