Spring Transaction - noRollbackFor won't commit when exception occurs

11,983

Solution 1

First, you catch the exception, so there is no way the Spring interceptor can see it and rollback the transaction.

And then, even if you didn't catch it, you've configured the method with **no**RollbackFor = {MailException.class}. This means that you don't want a rollback if this exception is thrown. Use rollbackFor = {MailException.class} instead.

Solution 2

Whenever you get exception, current transaction is rollbacked. No rollback rules, for those times when you do not want a transaction to be marked for rollback when an exception is thrown. Try to remove noRollbackFor annotation.

Also you should rethrow exception. Don't catch MailException.

Share:
11,983
AdrianS
Author by

AdrianS

Updated on August 07, 2022

Comments

  • AdrianS
    AdrianS over 1 year

    I want that if i get an E-Mail Exception, to NOT rollback the transaction.

    I am using HibernateTransactionManager and

    set  property name="nestedTransactionAllowed" value="true"
    

    because i have nested transactions.

    Also because i call this.getService() i have set

    lookup-method name="getService" bean="enrollmentProcessorService" .

    This way i should get the Spring Proxy.

    But if exceptions occurs, the transaction is still rolledback. my code looks like this:

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public void processConfirmation() throws SystemException {
            //do something
            this.getService().processConfirmationData(as400ContractId);
    
    
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {MailException.class})
    public void processConfirmationData(final long as400ContractDataId) throws SystemException {
        final AS400ContractData as400ContractData = this.readAS400ContractData(as400ContractDataId, false);
    
        this.populateEnrollmentOptionAnswers(as400ContractData.getContractData());
    
        final PersonalData personalData = this.readPersonalData(as400ContractData.getContractData()
                .getEpiphanyPersonalData().getPersonalData().getId(), true);
    
        try {
            personalData.setConfirmMailSent(true);
            as400ContractData.getContractData().getEpiphanyPersonalData().getPersonalData().setConfirmMailSent(true);
            this.personalDataDAO.flush();
            this.emailService.sendConfirmationMailToLOI(as400ContractData); //commit if exception is thrown here
        } catch (final DataAccessException dae) {
            LOGGER.error(CANNOT_UPDATE_PERSONAL_DATA_OBJECT, dae);
            throw new SystemException(StringUtils.EMPTY, CANNOT_UPDATE_PERSONAL_DATA_OBJECT, dae);
        } catch (final MessagingException e) {
            LOGGER.error(CANNOT_SEND_CONFIRMATION_EMAIL, e);
            throw new SystemException(StringUtils.EMPTY, CANNOT_SEND_CONFIRMATION_EMAIL, e);
        } catch (final MailException e) {
            Throwable rootCause = e.getRootCause();
            System.out.println("caught");