Отправка сообщения CXF JMS в транзакции - PullRequest
0 голосов
/ 18 октября 2018

Я использую CXF 3.2.6 и Spring 5.1.0 для создания веб-службы HTTP SOAP, которая использует JaxWsProxyFactoryBean для вызова (одностороннего) веб-службы через SOAP JMS.Я хотел бы, чтобы сообщение не отправлялось, если исключение происходит в (локальном) методе веб-сервиса.Поэтому я хотел бы, чтобы метод выполнялся в транзакции, которая фиксирует или откатывает отправку сообщения JMS.

Я попытался несколькими способами внедрить поведение транзакции. Я добавил аннотацию Transactional в MyHttpWebServiceImpl и определил бин JmsTransactionManager, создайтеJMSConfiguration, которая устанавливает менеджер транзакций и добавляет функцию к конечной точке.Однако это не имеет никакого эффекта.SetTransactionManager также устарел, но он не указывает, что я должен делать вместо этого.К сожалению, ActiveMQConnectionFactory также не имеет метода для установки менеджера транзакций.Я нашел очень мало документации о том, как транзакции Spring и CXF должны играть вместе.

Пример кода без поддержки транзакций:

@Service
public class MyHttpWebServiceImpl implements MyHttpWebService {
    private MyJmsWebService client;

    public void set(MyJmsWebService client) {
        this.client = client;
    }

    public MyResponse update(MyRequest request) {
        client.update(request);
        throw new RuntimeException("test rollback"); //doesn't work
    }    
}

@Configuration
public class MyConfiguration {
    // JMS webservice endpoint configuration ommitted
    private MyHttpWebService webService;

    @AutoWired
    public void setWebService(MyHttpWebService webService) {
        this.webService = webService;
    }

    @Bean
    public ConnectionFactory getConnectionFactory() {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
        factory.setBrokerURL("tcp://localhost:61616");
        return factory;
    }

    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    @Bean
    public Endpoint httpSoapEndpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), webService);
        endpoint.publish("/myws");
        return endpoint;            
    }

    @Bean
    public MyJmsWebService client() {
        return (MyJmsWebService) proxyFactoryBean().create();
    }

    @Bean
    public JaxWsProxyFactoryBean proxyFactoryBean() {
        String address = "jms:queue:MyQueue?sessionTransacted=true";
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setFeatures(Collections.singletonList(new ConnectionFactoryFeature(connectionFactory)));
        factory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
        factory.setServiceClass(MyJmsWebService.class);
        factory.setAddress(address);
        return factory;
    }
}
...