2014-11-24 1 views
0

저는 스프링 amqp를 사용하여 EJB (Stateless Session Bean) 내의 래빗 큐에 메시지를 배치하고 있습니다.래빗 AMQPTemplate 메시지는 EJB 트랜잭션 관리자가 관리합니다.

예외가 EJB 컨테이너 밖으로 던져지면 데이터 업데이트가 롤백됩니다. EJB 컨테이너가 메시지를 비슷한 방식으로 관리하는 방법이 있으므로 어쨌든 큐에 커밋 되기만하면됩니다. 예외가 발생하지 않고 EJB가 완료됩니까?

답변

0

그렇게 할 수있는 가장 좋은 방법은 다음과 같습니다

  1. 당신을 위해 TX 동기화와 함께 물건을 할 모든

  2. 사용 봄 TX 관리자

  3. 그리고 RabbitTemplate에서 EJB 제거하십시오 자동으로

EJB TX 동기 (커밋 또는 롤백)이 Spring에 의해 관리되지 않기 때문에 RabbitTemplate는, 현재 TX가 표시되지 않습니다와 문제.

EJB를 Spring 빈으로 만들 수 있다면 EJB 컨테이너 트랜잭션에 JtaTransactionManager을 제공하고 @Transactional으로 EJB 메소드를 표시 할 수 있습니다. 그러나이 경우 EJB는 의미를 가지지 않습니다. 왜냐하면 여기에서 Spring을 사용하여 eveything을 수행하기 때문입니다.

+0

감사합니다. 유감스럽게도 현재 기술 스택에서 EJB를 제거 할 계획이 있으므로이 방법은 저에게 적합하지 않습니다. EJB를 리팩터링하는 것을 꺼리는 것은 아니지만 다른 사람들을위한 것일 수도 있습니다. –

0

RabbitMQ에는 XA 가능 드라이버가 없으므로 컨테이너에서 관리 할 수 ​​없으므로 템플릿에서 channelTransacted을 설정하고 doInRabbit() 메서드로 EJB 코드의 범위를 지정하십시오.

template.execute(new ChannelCallback<Object>() { 
    @Override 
    public Object doInRabbit(Channel channel) throws Exception { 
     /// MDB logic + channel.basicPublish() 
    } 
}); 

그런 다음 예외가 발생하면 두 트랜잭션이 모두 롤백됩니다.

그러나 EJB 커밋이 실패하면 토끼 게시가 이미 커밋되어 롤백되지 않으므로 희귀 복제본을 처리해야합니다.

+0

감사합니다, 나는 ChannelCallback의 문서화 방법을 많이 알지 못합니다. AmqpTemplate이 아닌 RabbitTemplate을 사용해야한다는 것을 알았습니까? –

+0

실행 명령이 즉시 실행 되었습니까? async입니까? 건배 –

+0

http://docs.spring.io/spring-amqp/docs/latest-ga/api/org/springframework/amqp/rabbit/core/ChannelCallback.html 호출 스레드에서 실행됩니다. –