wood burning stoves*
The moose likes Other Application Frameworks and the fly likes Spring 2.5 - Rolling back first method, when the second method throws Runtime ex Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Frameworks » Other Application Frameworks
Bookmark "Spring 2.5 - Rolling back first method, when the second method throws Runtime ex" Watch "Spring 2.5 - Rolling back first method, when the second method throws Runtime ex" New topic
Author

Spring 2.5 - Rolling back first method, when the second method throws Runtime ex

Sam Gehouse
Ranch Hand

Joined: Jul 21, 2003
Posts: 281
Trying to rollback the previous write to database using Spring transaction for POC and learning purposes.

There are two functions that are part of the same transaction namely: insert and then update. The insert successfully writes to database using Hibernate 3.2. I throw a Runtime exception from update on purpose to exercise rollback of insert. Even though update throws the Runtime exception, the data inserted by insert method stays committed in database and does not get rolled back.

org.poc.tx.Manager class has insert and update methods.

Following is the XML:

<aop:config>
<aop ointcut
id="myOperation"
expression="execution(* org.poc.tx.Manager.*(..))"
/>
<aop:advisor
pointcut-ref="myOperation"
advice-ref="myTxAdvice"
/>
</aop:config>

<tx:advice id="myTxAdvice" >
<tx:attributes>
<tx:method
name="*"
read-only="true"
propagation="REQUIRED"
isolation="READ_COMMITTED"
timeout="5"
/>
</tx:attributes>
</tx:advice>

My assumption is, the above XML should run both Manager.insert() and Manager.update() within a single transaction will rollback insert(), if update() throws RuntimeException.

I have a main method that calls update and insert as follows:

public static void main(String args[]){
ApplicationContext ctx = new ClassPathXmlApplicationContext("my.xml");
Manager manager = (Manager) ctx.getBean("manager");
manager.insert();
manager.update();
}

The rollback successfully works, if I throw a RunTime exception inside insert method, right after successfully inserting the data as follows:

public void insert(final MyObj myObj){
HibernateCallback callback = new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException,SQLException {
session.insert(myObj);
throw new RuntimeException("ex thrown to rollback");
}
};
hibernateTemplate.execute(callback);
}

But if I want to spread it out to TWO separate methods in Manager class and want both the methods to participate in the same transaction, what should I do?

In a nutshell:

I want both Managaer.insert() and Manager.update() to participate in the same transaction.

I am invoking these two methods as follows in my main method:

manager.insert();
manager.update();

Can I invoke them separately and still make them participate in the same transaction?
Ritesh Agrawal
Ranch Hand

Joined: Jan 08, 2004
Posts: 74
Did you ever get a response to this question? I am facing the same issue.


Ritesh<br /> <br />SCJP 1.4<br />IBM Test 340<br />IBM AIX V4.0 Certified Professional<br /> <br />Right actions for the future are the best apologies for wrong ones in the past.<br />- Tyron Edwards
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

Wow, talk about waking the dead, that is almost a year old.

The answer is that he is not in a single transaction there. He has two transactions, one for each method, so the insert call started a transaction, completed and committed the transaction. Then the call to update creates a new transaction.

It is all because a call to manager.method is what is being wrapped by AOP. So if in the insert method it calls the update method directly, then it would all be in one transaction.

Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
kurt hanni
Ranch Hand

Joined: Aug 11, 2007
Posts: 140

Can I invoke them separately and still make them participate in the same transaction?

No you can't, because the scope of your transaction is in the manager class.

What you can do is make another method in your manager class to do your business logic (insert-then-update), then call this method in your main class
or
you can make your main class (class that calls insert then update) transactional. in this case insert-then-update is called in one method in your main class.

Its better practice to use the first approach.


SCJA, SCJP, SCJD, SCMAD, SCWCD, SCBCD, SCDJWS, SCEA, SOA, Spring Certified, OCP MySQL 5 Developer, PMP
Ritesh Agrawal
Ranch Hand

Joined: Jan 08, 2004
Posts: 74
Thanks for the responses.

Well, I tried to resolve the issue in a differnt way using Transactional Annotations. Below is the complete source code along with the application context. I have posted the same quesstion on Spring Forum at
http://forum.springsource.org/showthread.php?p=235791#post235791

Based on your explanation of not being in a single transaction, I had changed the code and put calls to two add methods in one method and made that method Transactional.

Please note that the posted JUnit Test case works fine and the first call to smartBaseBO.add is rolled back when the second call throws exception, but the same code is unable to roll back when used in an application. Thanks for helping me out with this.

Application Environment:

Spring 2.5.6
Hibernate 3.3.1 GA
Oracle 10g
tomcat 6.0.18



Ritesh Agrawal
Ranch Hand

Joined: Jan 08, 2004
Posts: 74
Hi folks,

Looks like the above code works fine when the log level for the hibernate package is set to DEBUG. When I set it to INFO, it doesnt work. Its a weird issue and I have no clue why this is working this way. I would be thankful, if someone can provide some insight into this.

Thanks.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Spring 2.5 - Rolling back first method, when the second method throws Runtime ex
 
Similar Threads
Spring transaction rollback aop config
Spring/Hibernate/Jboss/JTA/getCurrentSession()/createQuery is not valid without active transaction
transaction in spring
problems with JDBC transaction in Spring
Transaction doesn't rollback