2012-02-23 3 views
1

Spring 3.0.5, Hibernate 3.6.7 및 Atomikos Transactionessentials 3.7.0을 사용하고 있습니다. applicationContext.xml에서 AOP를 사용하여 구성된 트랜잭션. 모든 것이 제대로 작동합니다. (커밋, 롤백)JTA 트랜잭션 내부에서 발생한 예외를 잡는 방법은 무엇입니까?

제 의도는 jta 트랜잭션 내부에서 특정 예외를 throw하는 것입니다. 이렇게하면 트랜잭션을 롤백해야하고 롤백의 원인에 대한 자세한 정보를 얻을 수 있습니다.

문제는 내가 catch 할 수있는 유일한 예외는 트랜잭션이 예기치 않게 롤백되었음을 알리는 atomikos에 의해 발생하는 롤백 트랜잭션입니다.

거래 외부에서 어떻게 내 예외를받을 수 있습니까?

내 설명이 충분히 좋은지 잘 모르기 때문에 여기에 작은 예가 나와 있습니다. 이것은 내 의도가 무엇인지 데모 용입니다. 오타를 언급하지 마십시오.

public class MySpecialException extends Exception { 
    public MySpecialException(String someInfo) { 
     super(someInfo); 
    } 
} 

제외 던져 선언하는 방법 declareing 인터페이스 : 인터페이스를 구현

public interface MyInterface { 
    Object someJtaTransactionMethod(String param) throws MySpecialException; 
} 

하는 클래스 :

특정 예외는 (물론 일부 표준 예외가 될 수 있음)

그리고이 함수를 호출하고 전자를 포착하는 일부 코드 xceptions.

public class Caller { 

    @Autowired 
    private MyInterface callee; 

    public void test() { 
     try { 
      callee.someJtaTransactionMethod("Some test"); 
     } catch (MySpecialException mex) { 
      // I want to get here 
     } catch (Exception ex) { 
      // but I only get here 
     } 
    } 
} 

이것은 모두 가능합니까?

업데이트 : 물론 예외 원인을 살펴 보았습니다. 예외 자체는 org.springframework.transaction.UnexpectedRollbackException입니다. 원인은 javax.transaction.RollbackTransaction 클래스이며 원인은 com.atomikos.icatch.RollbackException입니다.

나는 Atomicikos가 예외를 알아 차리고 (원하는 경우) 롤백을 수행하지만, atomikos (다른 jta 구현 일 수도 있음)는 트랜잭션이 롤백 (예기치 않게)되었음을 나타내는 예외를 throw하고 내 예외는 사라 졌어.

업데이트 2 : 재미있는 점은 롤백해야하는 작업을 수행하지 않은 경우 원하는대로 예외를 잡을 수 있다는 것입니다.

업데이트 3 및 해결책 : JB Nizet은 해결책을 지적했습니다. 사실 내 트랜잭션은 의심 스럽지만 롤백되지 않았습니다.하지만 예외적으로 던져야하는 이유 때문에 컨트리어트 위반이 발생 했으므로 Atomicikos는 커밋에 예외를 던졌습니다. 이제는 예외를 위해 롤백하도록 트랜잭션을 구성 했으므로 모든 것이 예상대로 작동합니다.

+0

나는 Atomikos를 모른다. 그러나 그들이 당신의 예외를 잡아서 당신의 원인을 당신의 것으로 던질 수는 있겠는가? 두 번째 catch에서 예외의 getCause() 메소드가 반환 된 것을 분석 했습니까? –

+0

예 자세히 (한 번 이상 개발 중에) 예외를 살펴보고 디버깅을 시도했지만 아무 것도 찾을 수 없었습니다 ... 업데이트 된 게시물 – AlexS

+0

스택 추적 및 당신이 사용하고있는 프레임 워크? –

답변

3

귀하의 예외는 런타임 예외입니까?

런타임 예외가 발생하면 기본적으로 스프링 롤백되고, 확인 된 예외가 발생하면 기본적으로 커밋됩니다.

스택 트레이스에서 예외가 체크 된 예외이므로 Spring이 커밋하려고 시도하지만 JTA TM (Atomikos)이 커밋을 거부하기 때문에 (예 : 시간 초과로 인해) 커밋 할 수없는 것으로 보입니다.

이 예외로 인해 롤백이 발생하도록하려면 런타임 예외로 설정하거나 @Transactional 주석의 rollbackFor 속성에서 선언하십시오. 롤백이 발생해서는 안되는 경우 Atomikos가 커밋을 거부하는 이유 (너무 짧은 시간 초과, 다른 로그 ... 로그가 도움이 될 수 있음)를 찾으십시오.

+0

몇 가지 흥미로운 정보. 보통 이런 예외가 있다면, 나는 atomikos로 디버깅하고 실제 원인 (예를 들어, 일부 hibernate 또는 jdbc 예외)을 발견했다. 나는 내일 아침이 문제를 계속 조사 할 것이다. ..... 내 눈을 더 이상 뜨지 못하게 할 수있다. – AlexS

+0

고마워. 너는 내 하루를 구했다. 방금 Exception을 RuntimeException으로부터 상속 받도록 변경했습니다. 이제 모든 것이 원하는대로 작동합니다. 나는 그 atomikos가 내 자신의 예외를 던졌을 때 되돌아 가지 않았다는 것을 알지 못했고 예외적 인 던짐 때문에 어제 atomikos로 디버깅 할 수 없었습니다. – AlexS

0

MyException 대신 Exception에서 상속되는 MySpecialException을 던질 때 저에게 어떤 형식이 될까요?

그렇지 않으면 MyException 대신 MySpecialException을 catch하십시오.

+0

나는 이것이 단지 예일 뿐이며 오타가 문제가 아니라고 이미 말했습니다. 내 실제 코드를 컴파일하고 definitly 올바른 예외를 잡으려고합니다 (그렇지 않으면 컴파일러가 말해 줄 ...). – AlexS

관련 문제