2012-01-31 2 views
2

전자 메일 예외가 발생하면 트랜잭션을 롤백하지 않기를 원합니다. 내가 거래를 중첩 때문에Spring Transaction - noRollbackFor는 예외가 발생할 때 커밋하지 않습니다.

나는 HibernateTransactionManager

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

을 사용하고 있습니다. 내가 this.getService()를 호출하기 때문에

또한 내가

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

을 설정했습니다.

이렇게하면 스프링 프록시를 설치해야합니다.

그러나 예외가 발생하면 트랜잭션은 계속 롤백됩니다. 내 코드는 다음과 같습니다

당신은 예외를 얻을 때마다
@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"); 

답변

1

, 현재 트랜잭션이 롤백 할됩니다. 예외가 발생했을 때 트랜잭션이 롤백으로 표시되기를 원하지 않는 경우 롤백 규칙이 없습니다. noRollbackFor 주석을 제거해보십시오.

또한 예외를 다시 제기해야합니다. MailException을 잡아 내지 마십시오.

+0

보정 위의 구성에서 : 당신이 얻을 때마다 ** 런타임 ** 예외, 현재 트랜잭션이 롤백됩니다. –

+0

네, 맞습니다. EJB는 UserTransaction 어노테이션을 제공합니다. 아마도 봄에 비슷한 것이있을 것입니다. – Anton

2

먼저 예외를 잡으므로 Spring 인터셉터가 트랜잭션을보고 롤백 할 수있는 방법이 없습니다.

당신이 그것을 잡지 못하더라도, 당신은 **no**RollbackFor = {MailException.class}으로 방법을 구성했습니다. 즉, 이 예외가 발생하면 롤백을 원하지 않습니다. 대신 rollbackFor = {MailException.class}을 사용하십시오.

+2

나는 끔찍한 실수를 저질 렀습니다. 나는 그 트랜잭션이 예외를 위해 커밋하기를 원한다고 말하고 싶다. – Blitzkr1eg

+1

lookup 메소드가 실제로 프록시를 리턴하고 트랜잭션 인터셉터가 새로운 트랜잭션을 생성 하는지를 확인한다. 또는 코드를 리팩토링하고 requires_new 메소드를 다른 bean에 넣으십시오. 그러나 emailService 자체가 transactional이고 예외를 throw하는 경우 해당 메서드는 noRollbackFor로 표시해야합니다. –

+0

@JBNizet의 마지막 발언이 제 문제였습니다. 잘못된 메소드에서'noRollbackFor'를 사용했습니다. 예외를 잡는 곳이 아닌 예외를 throw하는 메소드 여야합니다. –

0

어제 같은 문제가 발생했습니다.

source : org.springframework.transaction.interceptor.TransactionInterceptor # invoke를 보았을 때.

문제가있는 곳을 찾았습니다.

this.emailService.sendConfirmationMailToLOI은 또 다른 서비스이므로 TransactionAttribute가 새로운 것입니다.

이 문제를 해결할 수

: @Transactional을 (전파 = Propagation.REQUIRES_NEW, noRollbackFor = {MailException.class})이 방법 (emailService.sendConfirmationMailToLOI *),

관련 문제