Я использую 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;
}
}