Announcement Announcement Module
Collapse
No announcement yet.
Can a MailSender participate in a transaction? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can a MailSender participate in a transaction?

    Hello,
    I would like for my mailAbonne method to be fully transactional. I noticed that even on a MailException being thrown the data is persisted by the dao (dao.persistMailingAbonnee(ma);). What's wrong with my configuration?
    Can anyone please help?
    Thanks in advance,
    Julien.

    Code:
      <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
            <property name="host" value="${mail.server}"/>
            <property name="port" value="${mail.port}"/>
        </bean>
    Code:
     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    Code:
        @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {MailException.class})
        private boolean mailAbonne(List<Sculpture> sculpturesChoisiesPourMailing, Abonne abonne) {
            try {
                for (Sculpture sculpture : sculpturesChoisiesPourMailing) {
                    MailingAbonnePK mapk = new MailingAbonnePK(sculpture.getSculptureID(), abonne.getAbonneID());
                    MailingAbonne ma = new MailingAbonne(mapk, new Date());
                    dao.persistMailingAbonnee(ma);
                }
                envoyerMail(sculpturesChoisiesPourMailing, abonne);
                return true;
            } catch (MailException e) {
                log.error("MailException");
                log.error(e);
                return false;
            }
        }

  • #2
    You have: @Transactional(..., rollbackFor = {MailException.class})

    AND

    ...} catch (MailException e) {
    ...}

    Don't catch the exception and rollback will be fine

    Comment


    • #3
      Hello gwa,
      What you say does make sense. I changed the method as you advised, however for some reason, the same behaviour as before is exhibited...
      Do you have other ideas?
      Regards,
      J.

      Comment


      • #4
        By the way the MailException was caught when I used the try/catch but now that I removed it, it is not thrown any more... very weird...

        Comment


        • #5
          ...or at least re-throw MailException after you catch it, and log the messages.

          Comment


          • #6
            Originally posted by davidparks21 View Post
            ...or at least re-throw MailException after you catch it, and log the messages.
            Hello David,
            I changed my method as shown below:
            Code:
             @Override
                @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {RuntimeException.class})
                public boolean mailAbonne(List<Sculpture> sculpturesChoisiesPourMailing, Abonne abonne) {
                    try {
                        for (Sculpture sculpture : sculpturesChoisiesPourMailing) {
                            MailingAbonnePK mapk = new MailingAbonnePK(sculpture.getSculptureID(), abonne.getAbonneID());
                            MailingAbonne ma = new MailingAbonne(mapk, new Date());
                            dao.persistMailingAbonnee(ma);
                        }
                        envoyerMail(sculpturesChoisiesPourMailing, abonne);
                        return true;
                    } catch (MailSendException e) {
                        log.error("MailException");//blocks here
                        throw new RuntimeException();
                    }
                }
            It blocks indefinitely now (see //block here)...
            Any idea why that is?
            Regards,
            Julien.

            Comment


            • #7
              It blocks on log.error??? What logging system are you using? I can't imagine any of the common logging systems doing that. Are you absolutely sure about what you're seeing? Try adding in some System.out.println(...) statements around it and other suspicious lines. You've got something bizzar happening.

              Fire up a debugger and walk through it line by line until you find the root method where it's blocking.

              Incidentally RuntimeException and Error (and subclasses) all trigger a rollback automatically, no need to define it in rollbackFor (unless you really just like being overly explicit about things). Checked exceptions do not trigger a rollback by default, so if you re-threw MailSendException, you'd have to define rollbackFor=MailSendException.

              Comment


              • #8
                Hello David,
                Sorry I meant it blocks here:
                Code:
                throw new RuntimeException();
                I tried removing the rollbackfor. It makes no difference.
                I even isolated the problem further by deliberately throwing a RuntimeException as shown here:
                Code:
                 @Transactional//(propagation = Propagation.REQUIRED, rollbackFor = {RuntimeException.class})
                    public boolean mailAbonne(List<Sculpture> sculpturesChoisiesPourMailing, Abonne abonne) {
                        try {
                            for (Sculpture sculpture : sculpturesChoisiesPourMailing) {
                                MailingAbonnePK mapk = new MailingAbonnePK(sculpture.getSculptureID(), abonne.getAbonneID());
                                MailingAbonne ma = new MailingAbonne(mapk, new Date());
                                dao.persistMailingAbonnee(ma);
                            }
                            envoyerMail(sculpturesChoisiesPourMailing, abonne);//deliberately throws a RuntimeException.
                            return true;
                        } catch (RuntimeException e) {
                            log.error("Exception");
                            log.error(e);
                            throw e;//blocks here
                        }
                    }
                it still blocks...
                J.

                Comment

                Working...
                X