Results 1 to 8 of 8

Thread: Rolling back on exception

  1. #1
    Join Date
    Mar 2009
    Location
    PHP
    Posts
    56

    Default Rolling back on exception

    Hello guys,

    I am just curious. If I have a DAO that has this method:

    PHP Code:
    public class MyDao extends DaoHibernateSupport {

         .....................

         public 
    Object save(Object object) {
             return 
    getHibernateTemplate.merge(object);
             
    // OR .saveOrUpdate(object);
         
    }

         .....................


    and I have a code like this:

    PHP Code:
    public class SomeClass {

         private 
    MyDao myDao;

         .....................

          public 
    void someMethod() {
              
    SomeTable1 table1 = new SomeTable1();
              
    SomeTable2 table2 = new SomeTable2();

              
    // some logic _ 1

              
    myDao.save(table1);


             
    // some logic _ 2


             
    myDao.save(table2);
          }

         .....................


    I would just like to ask if what happens when in the some logic _ 2 part an exception is thrown. Will the save on table1 be rolled back?

    I've asked this question because I consider the someMethod a single ATOMIC transaction. So if I cant do an insert in table1, I should not be able to do an insert on table2, and vice versa..

    Thanks guys for the advise

    -marcKun

  2. #2
    Join Date
    Aug 2006
    Location
    Arequipa-Peru / South America
    Posts
    2,796

    Default

    I would just like to ask if what happens when in the some logic _ 2 part an exception is thrown. Will the save on table1 be rolled back?
    It depends

    I've asked this question because I consider the someMethod a single ATOMIC transaction.
    You should do the follow, for each DAO create a BO (sometimes called service)
    each BO method (here it should be Transactional) should call each DAO method
    Something like
    Code:
    BO1 (call methodOneBo(...) Transactional to call methodOneDao(...)  in DAO1) 
           DAO1 (use methodOneDao(...) to work with the DB) 
    
    BO2 (call methodTwoBo(...) Transactional to call methodTwoDao(...)  in DAO2) 
           DAO2 (use methodTwoDao(...) to work with the DB)
    Now for your situation you should wrap both BO1-2 inside of other BO I mean
    BO3 -> BO1 and BO2, where BO3 must has a Transactional method wraping each method

    Code:
    BO3 ( use methodThreeBo(...) Transactionl to call: 
          BO1 use methodOneBo(...)  and BO2 use methodTwoBo(...) )
    Like all BOx are Transactional and BO3 Wraps BO1-2 and they are Transactional
    if your DAO2 fails, therefore the Transactional rollback in BO2 works, and like this BO2 is wraped with BO3 (again Transactional) it does that BO1 rollback too all stay in consistent state

    I hope you see my point

    I wrote time ago here
    Help For Transaction Logic For Business Object's

    Now the *It depends* in the beginning of my reply is that inside of DAO for each method you can do transactional too, therefore perhaps (not tested) your logic in your code would work.

    I suggest the first approach

    HTH
    - Manuel Jordan

    Kill Your Pride, Share Your Knowledge With All
    The Fear Of The LORD Is The Beginning Of Knowledge, But Fools Despise Wisdom And Discipline. Proverbs 1:7

    Blog


    Technical Reviewer of Apress

    • Pro SpringSource dm Server
    • Spring Enterprise Recipes: A Problem-Solution Approach
    • Spring Recipes: A Problem-Solution Approach, 2nd Edition
    • Pro Spring Integration
    • Pro Spring Batch
    • Pro Spring 3
    • Pro Spring MVC: With Web Flow
    • Pro Spring Security

  3. #3
    Join Date
    Mar 2009
    Location
    PHP
    Posts
    56

    Default

    Hello Sir,

    I think I get what you mean, but Im not sure how to do it. I have setup my hibernate-spring like this:

    hibernate.cfg.xml:

    PHP Code:
    .....
    <
    session-factory>
            <
    property name="connection.username">root</property>
            <
    property name="connection.url">jdbc:mysql://localhost:3306/crown</property>
            
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
            <
    property name="myeclipse.connection.profile">MySQL</property>
            <
    property name="connection.password"></property>
            <
    property name="connection.driver_class">com.mysql.jdbc.Driver</property>
            <
    property name="connection.autocommit">true</property>
            
            <!-- 
    Connection Pooling configusing cp30 -->
            <
    property name="hibernate.c3p0.max_size">5</property>
            <
    property name="hibernate.c3p0.min_size">1</property>
            <
    property name="hibernate.c3p0.timeout">5000</property>
            <
    property name="hibernate.c3p0.max_statements">0</property>
            <
    property name="hibernate.c3p0.acquire_increment">3</property>
            <
    property name="hibernate.c3p0.idle_test_period">300</property>
            
            <
    mapping class="model.Customers" />
            <
    mapping class="model.AccountInfo" />
            <
    mapping class="model.CreditLogs" />
    ......
        </
    session-factory
    and my applicationContext.xml like this:

    PHP Code:
        <!-- hibernate specific configuration -->
        <
    bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <
    property name="configLocation" value="classpath:hibernate.cfg.xml" />
        </
    bean>
        
        <
    bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <
    property name="sessionFactory" ref="sessionFactory" />
        </
    bean>

    <
    bean id="daoInterface" class="dao.implementations.SampleDaoImpl">
        <
    property name="sessionFactory" ref="sessionFactory" />
    </
    bean>
    <
    bean id="serviceInterface" class="service.implementations.SampleServiceImpl">
         <
    property name="daoInterface" ref="daoInterface" />
    </
    bean
    and my action class (or controller) will call service.save(object). service is instance of serviceInterface and save is a method of serviceInterface. Here is my sample code on SampleServiceImpl which implements serviceInterface.

    PHP Code:
    public class SampleServiceImpl implements ServiceInterface {
         private 
    DaoInterface daoInterface;

         
    //setters

         
    public Object save(Object o) {
             
    dao.save(o);
             
    // some logic to create an ActionLog object.
             
    dao.save(actionLog);
         }

    will this set up do? like when some logic to create an ActionLog object throws an exception, the transaction is rolled back? im not sure if my setup is transactional.

    thank you,.

    -marckun

  4. #4
    Join Date
    May 2007
    Location
    Saint Petersburg, Russian Federation
    Posts
    1,189

    Default

    Quote Originally Posted by marcKun View Post
    ...

    will this set up do? like when some logic to create an ActionLog object throws an exception, the transaction is rolled back? im not sure if my setup is transactional.

    thank you,.

    -marckun
    Your setup is not transactional. Check the reference for more details - 9. Transaction management

  5. #5
    Join Date
    Aug 2006
    Location
    Arequipa-Peru / South America
    Posts
    2,796

    Default

    and my action class (or controller) will call service.save(object). service is instance of serviceInterface and save is a method of serviceInterface. Here is my sample code on SampleServiceImpl which implements serviceInterface.
    seems that you didnt read well my previous post, about how to wrap many services(BO) inside of other service, the wrapper bo service should called by your controller

    like our friend denis told you read first such link

    let us know your advance

    Regards
    - Manuel Jordan

    Kill Your Pride, Share Your Knowledge With All
    The Fear Of The LORD Is The Beginning Of Knowledge, But Fools Despise Wisdom And Discipline. Proverbs 1:7

    Blog


    Technical Reviewer of Apress

    • Pro SpringSource dm Server
    • Spring Enterprise Recipes: A Problem-Solution Approach
    • Spring Recipes: A Problem-Solution Approach, 2nd Edition
    • Pro Spring Integration
    • Pro Spring Batch
    • Pro Spring 3
    • Pro Spring MVC: With Web Flow
    • Pro Spring Security

  6. #6
    Join Date
    Mar 2009
    Location
    PHP
    Posts
    56

    Default

    Quote Originally Posted by dr_pompeii View Post
    seems that you didnt read well my previous post, about how to wrap many services(BO) inside of other service, the wrapper bo service should called by your controller

    like our friend denis told you read first such link

    let us know your advance

    Regards
    Hmmm I really tried to read and understand your post and read the links you've given me. I know that the bottom line is to make my BO (service) 's method transactional right, so when an exception occured, the entire transaction will be rolled back.

    But I am having a hard time setting my services transactional. Here's what i did.


    PHP Code:
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <
    property name="configLocation" value="classpath:hibernate.cfg.xml" />
        </
    bean>
        
        <
    bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <
    property name="sessionFactory" ref="sessionFactory" />
        </
    bean>
        
        <!-- 
    the transactional advice -->
        <
    tx:advice id="txAdvice" transaction-manager="transactionManager">
            <
    tx:attributes>
                <!-- 
    all methods starting with get are read-only -->
                <
    tx:method name="get*" read-only="true"/>
                <!-- 
    other methods will get the default transaction settings AND ANY EXCEPTION should trigger a roll back-->
                <
    tx:method name="*" rollback-for="Exception"/>
            </
    tx:attributes>
        </
    tx:advice>
        
        <
    aop:config>
            <
    aop:pointcut id="services" expression="execution(* crown.services.implementations.*.*(..))"/>
            <
    aop:advisor advice-ref="txAdvice" pointcut-ref="services"/>
        </
    aop:config
    All my services implementations are placed in crown.services.implementations.* packages.

    Now what i did im my code is this:

    PHP Code:
    package crown.services.implementations

    public class SampleImpl {
        private 
    Dao dao;

        public 
    void setDao(Dao dao) {
           
    this.dao dao;
        }

        public 
    MyModel atomicTransaction(MyModel myModel) {
            
    dao.save(myModel);
           
             if(
    true) {
                 
    // this is for verying if a rollback is done
                 
    throws new Exception("Must rollback");
             }

             
    // logs this transaction
             
    dao.save(new LogModel(myModel));
             return 
    myModel;
        }

    But when I check the database after running the Test, the record is persisted. What have I lack in my configuration??

    Sorry, I really did try reading and reading before i started this thread but it seems myself is not enough.

    Please advise.

    -marckun
    Last edited by marcKun; Aug 19th, 2009 at 03:54 AM.

  7. #7
    Join Date
    Jan 2006
    Location
    Zürich, Switzerland
    Posts
    423

    Default

    Quote Originally Posted by marcKun View Post
    But when I check the database after running the Test, the record is persisted. What have I lack in my configuration??
    What does your test look like, including the configuration?

    - Sam

  8. #8
    Join Date
    Mar 2009
    Location
    PHP
    Posts
    56

    Default

    Quote Originally Posted by Sam Brannen View Post
    What does your test look like, including the configuration?

    - Sam
    sorry...

    iv just discovered my database table's engine is MyISAM.. i thought it was InnoDB. It's working smoothly now.

    Thank you
    -marckun

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •