[英]@Transactional method calling another method without @Transactional anotation?
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
.我在服务 class 中看到了一个方法,它被标记为@Transactional
,但它也在同一个 class 中调用了一些其他方法,这些方法没有被标记为@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?没有任何注释的方法的默认行为是由另一个带有@Transactional
注释的方法调用的?
When you call a method without @Transactional
within a transaction block, the parent transaction will continue to the new method.当您在事务块中调用没有@Transactional
的方法时,父事务将继续执行新方法。 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.它将使用来自父方法的相同连接(使用@Transactional
),并且在被调用方法中引起的任何异常(没有@Transactional
)将导致事务按照事务定义中的配置回滚。
If you call a method with a @Transactional
annotation from a method with @Transactional
within the same instance, then the called methods transactional behavior will not have any impact on the transaction.如果您在同一个实例中从带有@Transactional
的方法调用带有@Transactional
注释的方法,则被调用的方法的事务行为不会对事务产生任何影响。 But if you call a method with a transaction definition from another method with a transaction definition, and they are in different instances, then the code in the called method will follow the transaction definitions given in the called method.但是,如果您从另一个具有事务定义的方法调用具有事务定义的方法,并且它们在不同的实例中,则被调用方法中的代码将遵循被调用方法中给出的事务定义。
You can find more details in the section Declarative transaction management of spring transaction documentation .您可以在spring 事务文档的声明性事务管理部分找到更多详细信息。
Spring declarative transaction model uses AOP proxy. Spring 声明性事务 model 使用 AOP 代理。 so the AOP proxy is responsible for creation of the transactions.所以 AOP 代理负责创建事务。 The AOP proxy will be active only if the methods with in the instance are called from out side the instance.仅当从实例外部调用实例中的方法时,AOP 代理才会处于活动状态。
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 )例如,如果传播级别是NESTED ,则当前事务将“暂停”并创建新事务(注意:嵌套事务的实际创建仅适用于特定事务管理器)
The default propagation level ( what you call "behavior" ) is REQUIRED .默认传播级别(您称之为“行为”)是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 , eg "nothing new" is created.如果调用了带有@Transactional
注释的“内部”方法(或通过 XML 以声明方式进行事务处理),它将在同一个事务中执行,例如“没有新内容”被创建。
@Transactional marks the transaction boundary (begin/end) but the transaction itself is bound to the thread. @Transactional 标记事务边界(开始/结束),但事务本身绑定到线程。 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.如果调用具有@Transactional 注释的另一个方法,则传播取决于该注释的传播属性。
The inner method will affect the outer method if the inner method is not annotated with @Transactional.如果内部方法没有使用@Transactional 注解,内部方法将影响外部方法。
In case inner method is also annotated with @Transactional with REQUIRES_NEW
, following will happen.如果内部方法也使用带有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!");
}
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.内部方法使用REQUIRES_NEW
进行注释并引发 RuntimeException,因此它将其事务设置为回滚,但不会影响外部事务。 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.它们彼此独立运行,因此外部事务可以成功提交。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.