I have a setup where an outer method calls an inner method. It is possible that this inner method will throw an exception that will cause it to rollback. I don't want this exception to affect the outer method. To achieve this, I used @Transactional(propagation=Propagation.REQUIRED_NEW) on the inner method.
Here is a simplified version of my code:
public class ServiceAImpl implements ServiceA{
@Autowired
private ServiceB serviceB;
@Transactional(propagation=Propagation.REQUIRED)
public void updateParent(Parent parent) {
update(parent);
serviceB.updateChild(parent);
}
}
public class ServiceBImpl implements ServiceB {
@Transactional(propagation=Propagation.REQUIRED_NEW)
public void updateChild(Parent parent) {
checkIfChildHasErrors(parent.getChild()); //throws RuntimeException if Child has errors
update(parent.getChild());
}
}
public class Parent {
@Version
private Integer version;
private Child child;
//insert getters and setters
}
public class Child {
@Version
private Integer version;
//insert getters and setters
}
I am still new to Propagation but from my understanding, since the outer method (updateParent) has Propagation.REQUIRED and the inner method (updateChild) has Propagation.REQUIRED_NEW, they are now contained in their own separate transactions. If inner method encounters an exception, it will rollback but will not cause a rollback on the outer method.
When the outer method runs, it calls the inner method. The outer method is paused while the inner method is being ran. Once the inner method finishes, it is committed since it is a different transaction. The outer method unpauses. and it is also committed as another transaction.
The issue I am encountering is that the process of committing the outer method is triggering the optimistic locking for the Child class (probably because the value of the version field was changed after the inner method has ended and was committed). Since the outer method's instance of Child is already outdated, committing it triggers optimistic locking.
My question is: IS THERE A WAY TO PREVENT THE OUTER METHOD FROM TRIGGERING OPTIMISTIC LOCKING?
I am surprised that the outer method even tries to commit changes to the Child class. I assumed that since the inner method is contained in its own transaction, the outer method's transaction will no longer include the updateChild method.
I am using Spring 3.0.5 with Hibernate 3.6.10