Question

My requirement is to save data in 5 tables through 5 methods . These 5 methods are wrapped under single parent method which is annotated with @Transactional.

Am calling this parent method 100 times in a loop.

Constraints are

  1. Transaction has to be rolled back even if one method fails in one iteration.(i.e 5 methods has to be saved without exception) and the flow should continue for next iteration.

  2. One iteration fail should not rollback all the other iterations. I.,e In 100 iterations if 5th iteration fails and all the other iterations are succeeded, then all the 99 iteration's operations should get committed.

  3. It is OK if transaction is committed after successfully executing all the 5 methods in one iteration.

Issue is

  1. If, 5th iteration is failed, then in next iteration, old values are showing in the entity. I have used session.clear() method in catch block to avoid that. is that correct? But the issue is,
    even after successful insertion of five methods in next iteration, the transaction is getting rolled-back. And all the previous 4 iteration's data state in session is getting cleared.

am using Spring 3.2, Hibernate3, HibernateTransactionManager

Was it helpful?

Solution

I forgot to write the caller method and calling method in different beans. Hence it is getting rolled back. Spring Transaction uses AOP. A proxy is created for the methods which are annotated with @Transactional. This bean method should be called from another bean, which I got form the Spring documentation

OTHER TIPS

You want your iterations succeed or fail independently one from another. You want a failure in any of the 5 steps of the individual iteration to fail entire iteration and to roll back the corresponding transaction.

It is clear that you want to have transaction boundary at the level of the service call that corresponds to a single iteration. Now, the rule of the thumb is to allocate a Hibernate session per transaction. So, a Hibernate session should be created at the beginning of each iteration and be disposed of at the end. That would prevent random junk, like entites that failed to be persisted to the database in the previous trnsactions, from showing up in the Hibernate session.

Hope this helps.

Have a look into propagation levels of spring transactions here and choose whatever best suits your requirements. An example which does what you need is as follow (you may mark myService as @Transactional as well) but you might like to have a look at other levels.

public void myService() {
    // call myTaskCaller as many times as you like
}

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void myTaskCaller() {
    task1();
    task2();
    task3();
    task4();
    task5();
}

private void task1(){}
private void task2(){}
private void task3(){}
private void task4(){}
private void task5(){}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top