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

时间:2015-11-17 17:07:58

标签: java spring transactions

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

@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时都会创建一个新事务。 Howether,如果我删除标有“##”的行,则只为整个过程创建一个事务,允许在发生任何异常时回滚。

  1. 这是预期的弹簧行为吗?
  2. 有没有办法保持CalledService事务处理并避免在从CallerService转到CalledService时创建新事务?
  3. 请注意,我确实尝试将传播更改为“必需”以及CalledService上的其他几个值。

    编辑: 这是来自persistData的堆栈跟踪:

    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 个答案:

答案 0 :(得分:0)

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