Spring事务 - 发生异常时noRollbackFor不会提交

时间:2012-01-31 13:04:46

标签: java spring transactions rollback

我希望如果我收到电子邮件异常,则不要回滚事务。

我正在使用HibernateTransactionManager

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

因为我有嵌套的交易。

另外因为我打电话this.getService()我已经设置了

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

这样我应该得到Spring Proxy。

但是如果发生异常,事务仍然会回滚。 我的代码看起来像这样:

@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");

3 个答案:

答案 0 :(得分:2)

首先,您捕获异常,因此Spring拦截器无法看到它并回滚事务。

然后,即使你没有抓住它,你也用**no**RollbackFor = {MailException.class}配置了方法。这意味着如果抛出此异常,想要回滚。请改用rollbackFor = {MailException.class}

答案 1 :(得分:1)

每当您获得异常时,当前事务都会被回滚。没有回滚规则,因为当您不希望在抛出异常时将事务标记为回滚时。尝试删除noRollbackFor注释。

此外,您应该重新抛出异常。不要捕获MailException。

答案 2 :(得分:0)

昨天,我遇到了同样的问题。

当我看到源:org.springframework.transaction.interceptor.TransactionInterceptor #accoke。

我发现了问题所在。

this.emailService.sendConfirmationMailToLOI 是另一个服务,因此TransactionAttribute是新的。

你可以解决这个问题:  @Transactional(propagation = Propagation.REQUIRES_NEW,noRollbackFor = {MailException.class}) 在此方法(emailService.sendConfirmationMailToLOI *)中,上面的配置