Отправляйте сообщение JMS только после фиксации транзакции JPA. - PullRequest
0 голосов
/ 23 мая 2018

Я работаю над проектом, в котором используются Spring JmsTemplate, ActiveMQ и Hibernate.У меня есть метод, завернутый в транзакцию, который отправляет сообщение через JmsTemplate, выполняет немного больше работы и затем возвращает, чтобы транзакция могла зафиксироваться.Я хочу, чтобы сообщение отправлялось только после совершения транзакции, т. Е. JmsListener должен срабатывать только после возврата вышеупомянутого метода.

Возьмите отправителя и получателя следующего примера:

@Service
@Transactional
public class TestService{

  @Autowired
  private JmsTemplate jmsTemplate;

  public void test() throws InterruptedException {
    jmsTemplate.convertAndSend("test_queue", "Test");
    Thread.sleep(1000L);
    System.out.println("This should run first");
  }
}

@Service
@Transactional
public class Listener {

  @JmsListener(destination = "test_queue", containerFactory = "jmsListenerContainerFactory")
  public void onMessage() {
    System.out.println("This should run last.");
  }
}

Я хочутекст «Это должно запуститься первым», чтобы напечатать перед «Это должно запуститься последним», но из-за Thread.sleep этого никогда не происходит!Я попытался внести ряд изменений в конфигурацию на моем jmsListenerContainerFactory, но ни одно из них не имеет значения.

Не уверен, что в этом случае задействован XA.Является ли фактическая отправка сообщения частью отдельной транзакции?Если это так, то проблема, вероятно, в том, что две транзакции не синхронизируются, но я не знаю, как это решить.

1 Ответ

0 голосов
/ 23 мая 2018

Мне нужно было установить Session Transacted на JmsTemplate вместо JmsListenerContainerFactory:

@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
    JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
    jmsTemplate.setSessionTransacted(true);
    return jmsTemplate;
}
...