当前位置: 首页 > 知识库问答 >
问题:

为什么当我调用另一个服务的方法时会创建新的spring事务?

秦才
2023-03-14

我有两项服务。一个从数据库加载数据,修改它们并调用另一个服务来保留修改后的数据:

@Service
@Transactional
public class CallerService {

    public void doSomething() {
        List dataList = loadData();
        for(data : dataList) {
            data.setValue("newValue");
            calledService.persistData(data);
        }
    }
}

@Service
@Transactional //##
public class CalledService {
    public void persistData(Data data){
        myDao.persistData(data);
    }
}

使用这样的代码,每次调用CalledService.persistData时都会创建一个新的事务。然而,如果我删除了标有“##”的行,那么整个流程只创建了一个事务,允许在发生任何异常时回滚。

  1. 这是预期的Spring行为吗?
  2. 有没有办法保持被叫服务事务性,并避免在从调用方服务转到被叫服务时创建新事务?

请注意,我确实尝试在CalledService上将传播更改为“Required”和其他几个值。

编辑:这是来自持久数据的堆栈跟踪:

CalledServiceImpl.persistData(Reglement, int, Gestionnaire) line: 304   
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57  
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
Method.invoke(Object, Object...) line: 606  
AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) line: 317 
ReflectiveMethodInvocation.invokeJoinpoint() line: 190  
ReflectiveMethodInvocation.proceed() line: 157  
TransactionInterceptor$1.proceedWithInvocation() line: 99   
TransactionInterceptor(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 281    
TransactionInterceptor.invoke(MethodInvocation) line: 96    
ReflectiveMethodInvocation.proceed() line: 179  
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 207   
$Proxy51.persistData(Data) line: not available  
CallerServiceImpl.doSomething(String) line: 277 
CallerServiceImpl.runBatch(String[]) line: 178  
CallerServiceImpl(BatchAbstractService).doBatch(String[]) line: 29  
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57  
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
Method.invoke(Object, Object...) line: 606  
AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) line: 317 
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 201   
$Proxy95.doBatch(String[]) line: not available  
ClientBatch.process(String, String[]) line: 78  
ClientBatch.main(String[]) line: 53 

EDIT2: CallerService和CalledService不在同一个项目中。如果我将它们放在同一个项目中,当流程中出现异常时,事务会相应地回滚。

共有1个答案

曾洲
2023-03-14

强制传播。需要支持当前事务,而不是创建新事务。删除Transactional注释是一种不好的做法,因为调用方需要事务行为,而且方法本身可能不安全

 类似资料:
  • 问题内容: 为了了解Spring事务的工作原理,我想知道在以下情况下发生的情况:如果一种方法标记为,而另一种方法标记为。 假设配置使用所有默认设置。 现在,如果我要输入,显然可以开始交易。然后,钻进去会发生什么?交易已经存在的事实会导致没有新的交易诞生,还是我在这里创建两个交易? 关于Propagation的文档(在下面引用)似乎涵盖了这一点,但是我想验证一下我的理解 Propagation:通常

  • 问题内容: 为了了解Spring事务的工作原理,我想知道在以下情况下会发生什么情况,其中一种方法标记为,而另一种方法标记为。 假设配置使用所有默认设置。 现在,如果我要输入,显然可以开始交易。然后,钻进去会发生什么?事务已经存在的事实会导致没有新的事务诞生,还是我在这里创建两个事务? 关于传播的文档(在下面引用)似乎涵盖了这一点,但是我想验证一下我的理解,这对于我的处女大脑来说可以一次理解所有知识

  • 我有一个database.xml来定义spring事务,比如 和我的dao,服务都在utils包或子包中,比如: 提前感谢您的帮助和建议!

  • while(true)连续传递这些指令,但仅当accept()方法单击时才创建线程? 新线程是否有专用端口?套接字通信不是一对一的吗? 软件如何跟踪生成的套接字线程,这实际上有关系吗? 如何向刚写给我的线程发送答复? 也许是因为我缺乏谷歌技能,但我找不到一个好的教程来做这件事:帮助?

  • 这是一个非常基本的OOP问题。但我对全班的行为不太清楚。所以假设我有a类: 现在,当我调用类A的方法输出: 产出将是: 附注。希望我洗清了自己的罪名。

  • 问题内容: 在Spring中,带有注释的方法 将获得一个新的事务(如果还没有),但是我注意到,如果从非事务处理方法调用事务方法,则不会获得任何事务。这是代码。 是一个常规方法,该方法调用是事务性的,但不会保留任何更改。 我正在使用Spring 3和Hibernate3。在这里我做错了什么?谢谢。 问题答案: 这是Springs AOP的局限性之一。因为dao bean实际上是在spring时创建的