I have two services. One loads data from DB, modify them and calls another service to persist the modified data:
@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);
}
}
With such code, a new transaction is created each time CalledService.persistData is called. Howether, if I remove the line marked with "##", only one transaction is created for the whole process, allowing rollback in case any exception occurs.
- Is this the expected spring behavior ?
- Is there a way I could keep CalledService transactional and avoid new transactions to be created when going from CallerService to CalledService ?
Please note that I did try to change the propagation to "Required" and several other values on CalledService.
EDIT: Here is the stacktrace from 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 and CalledService are not in the same project. If I put them in the same project, the transaction is rolled back approriately when an exception occurs in the process.