Trying to prevent rollback of inner transactions. if inner transactions response not SUCCESS then outer transactions should rollback but inner transaction should save data.
@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)
private void test1(Account account) throws Exception {
DOA.save(account);
status = test2(account);
if(status!='SUCCESS'){
throw new Exception("api call failed");
}
}
@Transactional(propagation=Propagation.MANDATORY)
private void test2(Account account) {
response //API Call
DOA.save(response);
return response.status;
}
Configure the inner transactional method as Propagation.REQUIRES_NEW
such that it will always commit (ie save the data) when the method completes whether the outer transactional method rollbacks or not.
Also, make sure outer method does not self invocation the inner method as @Transactional
does not work in this case (See Method visibility and @Transactional section in docs ).
They should reside in different beans which the outer method calls the bean of the inner method:
@Service
public class Service1 {
@Autowired
private Service2 service2;
@Transactional(rollbackFor=Exception.class)
public void test1(Account account) throws Exception {
DOA.save(account);
status = service2.test2(account);
if(status!='SUCCESS'){
throw new Exception("Api call failed");
}
}
}
@Service
public class Service2{
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void test2(Account account) {
response // API Call
DOA.save(response);
return response.status;
}
}
@Transactional
is ignored for your Test2
method and the call is part of single transaction.
two things to consider here as Spring doc says -
Method visibility and @Transactional
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.
Proxy mode
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.
If you want to save data for inner method you can choose to start new Transaction for Test2
method so it does not impact existing transaction started by Test1
.
But it will not start the new Transaction in your case even if you make Test2
public cuase its called from the same class.
Solution -
Propagation.REQUIRES_NEW
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.