Vaandu Vaandu - 1 month ago 20x
Java Question

Spring Transaction - automatic rollback of previous db updates when one db update failes

I am writing a simple application (Spring + Hibernate + PostgreSql db). I am just trying to construct a sample object and persist in db.

I run a simple java class main method where i have loaded the applicationContext and have got reference to the service class as below

TestService srv = (TestService)factory.getBean("testService");

Application Context - context :

<bean id="transactionManager"
<property name="sessionFactory" ref="sessionFactoryVsm" />

<bean id="testService" class="com.test.service.TestServiceImpl">
<property name="testDao" ref="testDao"/>

<bean id="testDao" class="com.test.dao.TestDaoImpl>
<property name="sessionFactory" ref="sessionFactoryVsm"/>

In TestService I have injected TestDao. In test service method I have constructed to employee objects
emp1 and emp2 and calling dao twice to update.

TestDaoImpl code:

public void saveOrUpdate(BaseDomainModel baseObject) {

Session session = null;
try {
session = getHibernateTemplate().getSessionFactory().openSession();
} catch (Exception e) {
logger.error("Generic DAO:saveOrUpdate::" + e);
} finally {
if (session != null) {


When emp2 update fails emp1 should also fail. How do I do that. Please advice

Thanks in advance

Updated :

Thanks Nanda. I tried Declarative transaction. But it is not working. emp1 gets persisted and not rolled back eveb second dao call fails. I have added transaction advice to the method.

to test if the transaction advice is applied or not i changed the propagation to "NOT_SUPPORTED". but still emp1 gets persisted. the expectation is we should have got Transaction Not Supported type of exception. please advice .


@seanizer - Thanks for the update. I have even tried adding

public void saveEmp(Employee emp)
to that service method. But it didn't work. Moreover iterating the collection hold good only if i need to call one dao. If in case i have to call two different dao to persist obj1 and obj2- this may not help. Just to check if the transaction is getting applied I get
But still obj1 got persisted.
I just doubt if the xml configuration/ annotation given is correct. please check

<bean id="txManager"
<property name="sessionFactory" ref="sessionFactoryVsm" />

<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:method name="saveEmp" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="*"/>
<aop:pointcut id="testServiceOperation" expression="execution(*com.test.service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="testServiceOperation"/>

I am using org.springframework.orm.hibernate3.HibernateTransactionManager for the transactionManager. Is this correct ?


I have created my exception class myRuntimeExp extending from RuntimeException and throwing the same from Dao method to the service method. but still the rollback is not happening. I just doubt if I have correctly given the configurations in the applnContext.xml. Can someone help me how to check if the transaction advice / annotation is being applied to the method or not? is there any way of running it in a debugging mode and check

Issue :

I was using

session = getHibernateTemplate().getSessionFactory().openSession();

But it should be current session and it is working fine.

session = getHibernateTemplate().getSessionFactory().getCurrentSession();


If you use declarative transaction management, you can lose most of this boilerplate:


private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory f){
    this.sessionFactory = f;

public void saveOrUpdate(BaseDomainModel baseObject) {
    Session session = sessionFactory.getCurrentSession();

And you can control the transaction handling from the service layer using @Transactional (or xml configuration)


private TestDao testDao;

public void setTestDao(TestDao  d){
    this.testDao = d;

@Transactional // one transaction for multiple operations
public void someServiceMethod(Collection<BaseDomainModel> data){
     for(BaseDomainModel baseObject : data)