Results 1 to 6 of 6

Thread: Declarative transaction management

  1. #1
    Join Date
    Feb 2005
    Location
    Norway
    Posts
    18

    Default Declarative transaction management

    Hi all,

    I'm using Spring 1.1.5 with Hibernate 2.1.8.

    I have a business service class that does two db calls and sends a mail. I have declared a transaction manager with declarative transaction management. I only want to send mail if both db calls are successfull, and I want to rollback the two db calls if sending of the mail fails.

    Bean declarations:
    Code:
    <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
        <property name="transactionManager">
            <ref bean="hibernateTransactionManager" />
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>
        </property>
    </bean>
    
    <bean id="myServiceManager" parent="baseTransactionProxy">
        <property name="target">
            <bean id="myTarget" class="com.mycomp.myapp.service.impl.MyManagerImpl">
                <property name="dao1"><ref bean="dao1"/></property>
                <property name="dao2"><ref bean="dao2"/></property>
                <property name="mailSender"><ref bean="mailSender"/></property>
            </bean>
        </property>
    </bean>
    Java code:
    Code:
    public void saveData&#40;Data d&#41; &#123;
        dao1.save&#40;d.getSomething&#40;&#41;&#41;;
        logger.debug&#40;"dao1"&#41;;
        dao2.save&#40;d.getSomethingElse&#40;&#41;&#41;;
        logger.debug&#40;"dao2"&#41;;
        mailSender.send&#40;createMessage&#40;d&#41;&#41;;
        logger.debug&#40;"mail"&#41;;
    &#125;
    dao1 and dao2 are classes extending HibernateDaoSupport and use HibernateTemplate to save objects.

    This works as intended when the db calls are ok and mailsending fails, but mails are sent even if the db calls fail.

    I can see in my logs that all three calls in the saveData method is called even if the first one fails.

    - How can I make the transaction manager return from the method if the first call fails?
    - Is it possible with declarative transaction management, or do I need to look more into programmatic management?
    - Any tips to change my code to make this happen?

    Thanks in advance

    Trond

  2. #2
    Join Date
    Aug 2004
    Location
    Melbourne, Australia
    Posts
    1,104

    Default

    but mails are sent even if the db calls fail..Is it possible with declarative transaction management, or do I need to look more into programmatic management?
    Mail is generally not a transactional resource - so you'll hve to detect if the transaction is marked for rollback.

  3. #3
    Join Date
    Feb 2005
    Location
    Norway
    Posts
    18

    Default

    Quote Originally Posted by katentim
    Mail is generally not a transactional resource - so you'll hve to detect if the transaction is marked for rollback.
    Anyone have an idea to how I might do this?

  4. #4
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    You have to apply probably a programatic transaction demarcation and fire the email after the transaction has ended succesfully. Basically you'll send the email only if everything went okay because you can't roll back a sent email.
    You can for example put the emails into a pool of jobs for a scheduler (see Quartz) this way taking advantage of the asynchronous nature of messages in general.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  5. #5
    Join Date
    Aug 2004
    Location
    Leuven, Belgium
    Posts
    37

    Default

    We store our outgoing mails in a database table as part of the transaction.
    A background task retrieves these mails one by one from the database,
    sends them and then deletes them from the database.

    Advantages:
    a) transactional: if something fails, everything is rolled back
    b) faster, main transaction does not wait for smtp server
    c) if background task can't send email (eg. smtp server down) the mail
    stays in the database, and sending is retried later

    Maarten

  6. #6
    Join Date
    Aug 2004
    Location
    Germany, Magdeburg
    Posts
    279

    Default

    Very good solution, I should write this down. What latenzy in email sending is added by the seperated worker threads?

    You have to apply probably a programatic transaction demarcation
    That is not always necessary. You can fetch the status of the current transaction (even if the transaction is declarative). But I would go for the programatic solution, too - just to avoid using an advice and to make things explicit.

Similar Threads

  1. Replies: 0
    Last Post: Jun 6th, 2005, 06:22 AM
  2. Replies: 6
    Last Post: May 17th, 2005, 11:38 PM
  3. Transaction Management
    By caverns in forum Data
    Replies: 3
    Last Post: Mar 8th, 2005, 06:38 AM
  4. Replies: 3
    Last Post: Nov 19th, 2004, 07:16 PM
  5. Transaction pb Hibernate/MySQL
    By syluser in forum Data
    Replies: 2
    Last Post: Aug 28th, 2004, 02:40 PM

Posting Permissions

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