我在服务类中看到了一个标记为 @Transactional
的方法,但它也调用了同一类中未标记为 @Transactional
的一些其他方法。
这是否意味着对单独方法的调用导致应用程序打开与数据库的单独连接或暂停父事务等?
没有任何注释的方法被另一个带有 @Transactional
注释的方法调用的默认行为是什么?
当您在事务块中调用不带 @Transactional
的方法时,父事务将继续执行新方法。它将使用来自父方法的相同连接(带有 @Transactional
),并且在被调用方法(不带 @Transactional
)中引起的任何异常都将导致事务按照事务定义中的配置回滚。
如果您从属于同一个 Spring Bean
的具有 @Transactional
的方法调用具有 @Transactional
注释的方法,则被调用方法的事务行为不会对事务产生任何影响。但是如果你从另一个具有事务定义的方法调用具有事务定义的方法,并且它们属于不同的 SpringBean
,那么被调用方法中的代码将遵循自己的事务定义。
您可以在 spring transaction documentation 的声明性事务管理部分找到更多详细信息。
Spring 声明式事务模型使用 AOP 代理,因此 AOP 代理负责事务的创建。只有当被调用的方法属于与调用者不同的 Spring Bean
时,AOP 代理才会处于活动状态。
这是否意味着对单独方法的调用导致应用程序打开与数据库的单独连接或暂停父事务等?
这取决于 propagation level。以下是所有可能的级别 values。
例如,如果传播级别为 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,因此它将其事务设置为回滚,但不会影响外部事务。外部事务在内部事务开始时暂停,然后在内部事务结束后恢复。它们彼此独立运行,因此外部事务可以成功提交。
will follow the transaction definitions given in the called method
的意思。但是如果调用来自同一个对象实例,它不会产生任何影响,因为调用不会通过负责事务维护的 aop 代理传播。@Transactional
定义的方法,那么即使调用方法具有不同的@Transactional
属性,被调用的方法也将遵循它自己的事务定义.