2017-09-29 4 views
2

기본 메시지 리스너 컨테이너를 사용하고 있습니다. 구성에서 세션 트랜잭션 속성을 true로 설정했습니다.JMS 리스너에서 예외가 발생하면 어떻게됩니까

onMessage() 방법은 이것이다 :

public void onMessage(Message message) { 
    try { 
     // Some code here 
    } catch (JmsException jmse) { 
     log.error(jmse); 
    } catch (Throwable t) { 
     log.error(t); 
    } 
} 

당신은 내가 catch 블록에서 예외를 처리하고 볼 수 있듯이.

내 요구 사항은 JMS 예외 인 경우 재전송해야한다는 것입니다. 즉, 트랜잭션 롤백이있을 때 발생하는 메시지가 리스너/소비자에게 다시 전달되어야합니다. 어떻게 그럴 수 있습니까?

여기서 수동으로 트랜잭션을 롤백 할 수 있습니까? 나는 그것이 가능한 해결책이라고 생각하지만 코드에서 그렇게하는 방법을 모르겠습니다.

또 다른 일반적인 질문 :

나는 catch 블록을 통해 가능한 모든 예외를 처리하고 있기 때문에, 나는 내가 catch을 통해 가능한 모든 예외를 처리하고 있기 때문에 메시지 재전송 즉, 트랜잭션 롤백의 시나리오 없을 것 같아요 블록. 내가 맞습니까?

답변

0

SessionAwareMessageListener를 사용해 보셨습니까? 확인해주세요 here

+0

은 무엇입니까? 그래서 현재 내 클래스는 메시지 리스너를 구현합니다. 이제 sessionawaremessagelistener를 구현해야합니다. – africandrogba

+0

또한 세션 객체를 통해 수동으로 확인하고 필요한 경우 세션 객체를 통해 catch 블록에서 롤백을 호출해야합니다. 나는 이것이 당신이 내가 그것을 실행해야한다고 말하는 방식이라고 믿습니다. – africandrogba

+0

이 인터페이스에서 세션 객체를 얻었으므로 요구 사항에 따라 트랜잭션을 롤백하거나 커밋 할 수 있습니다. – manoj

2

SessionAwareMessageListener은 필요하지 않습니다. 잡기 대신 예외를 던지면 컨테이너가 전달을 롤백합니다.

특히 예외가 JmsException, RuntimeException (또는 하위 클래스) 또는 Error 인 경우 롤백됩니다.

어쨌든 Throwable을 잡아서는 안됩니다. 좋은 습관이 아닙니다.

편집

public void onMessage(Message message) { 
    try { 
     // Some code here 
    } 
    catch (JmsException jmse) { 
     log.error(jmse); 
     // Do some stuff 
     throw new RuntimeException(jmse); // JMSException is checked so can't throw 
    } 
    catch (RuntimeException e) { 
     log.error(e); 
     throw e; 
    } 
    catch (Exception e) { 
     log.error(t); 
     throw new RuntimeException(e); 
    } 
} 
+0

Throwable을 잡기 위해 사용하고 있기 때문에 throwable은 모든 예외와 오류의 부모 클래스이므로 모든 가능한 예외를 잡아 내지 않습니다. – africandrogba

+0

예, 그렇지만 Throwable을 "먹는"것은 좋지 않습니다. OOM과 같은 '오류'일 수 있습니다. 어쨌든, 롤백을 강제하기 위해서는 메서드 서명이 그것을 허용하지 않기 때문에 그것을 다시 던질 수 없기 때문에'RuntimeException'에'Throwable'을 래핑해야 할 것입니다. –

+0

코드를 통해 설명 할 수 있습니까? 나는 코드에서 말하는 것을 구현하는 방법을 모른다. – africandrogba

관련 문제