How to call multiple http webservice on mule thread in transaction?
I'm new to the mule. I have a wm6-hyernate mule setup. Suppose there are 3 webservice.Aim to call all these web services on a mule thread so that all 3 are in a transaction. so suppose if the 3rd webservice fails, the previous 2 will be automatically dropped.
Here is my code snippet that I tried. my mule-flow.xml ( currently I have only one webservice,kindly let me know how can I add multipe webservice call in flow?
)
<spring:beans>
<spring:import resource="classpath:spring-mule.xml"/>
<spring:import resource="classpath:applicationContext-persistence.xml"/>
</spring:beans>
<flow name="addCustomer" doc:name="addCustomer">
<http:inbound-endpoint exchange-pattern="request-response"
address="http://localhost:8081/pos/addCustomer" doc:name="HTTP" />
<cxf:simple-service serviceClass="com.proj.pos.webservice.interfac.CustomerService" doc:name="SOAP"/>
<component ><spring-object bean="customerService"/></component>
</flow>
</mule>
My spring-mule.xml
<bean id="customerService" class="com.proj.pos.webservice.implementation.CustomerServiceImpl">
<property name="cusDao" >
<ref local="customerDao"/>
</property>
</bean>
Mine: ApplicationContext-persistence.xml
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="username" value="xyz" />
<property name="password" value="xyz" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="customerDao" class="com.proj.pos.dao.implementation.CustomerDaoImpl">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
my CustomerServiceImpl
@WebService(endpointInterface = "com.proj.pos.webservice.interfac.CustomerService",
serviceName = "CustomerService")
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerDao cusDao;
@Transactional //NOTE:USING THIS ANNOTATION I AM ABLE TO ACHIEVE THE BELOW METHOD //IN TRANSACTION,BUT I BELEIVE THIS FEATURE WILL NOT WORK IF WE HAVE MULTIPLE WEBSERVICE CALL
@Override
public Customer addCustomer(CustomerDto dto) {
Customer customer=new Customer(dto.getCustomerId(), dto.getFname(), dto.getLname(), dto.getAge(), dto.getDateOfBirth(), dto.getAddress());
customer.setCustomerId(cusDao.persist(customer));
return customer;
}
public CustomerDao getCusDao() {
return cusDao;
}
public void setCusDao(CustomerDao cusDao) {
this.cusDao = cusDao;
}
}
Please let me know any solution. thank
source to share
After seeing your question, I realized that you are trying to make 3 web service calls and want to make all three calls in one transaction.
As you call another system (a web service in your case), you cannot control the transaction.
In your case, you can use Scatter data collection router to call three webservices, if any route (webservice call) fails it will throw CompositeRoutingException
, you can catch this exception very well in your catch exception strategy.
In your catch-exclusion strategy, you need to perform rollback operations (make another web service call or db call that will fulfill your rollback requirements).
source to share
As I understand it, you have three or more webservice calls and some db operations. you want to rollback if any call to the service failed.
Write a spring bean like below for SpringTransactionFactory and set the transationManager property (link from your appContext-persistence.xml)
<spring:beans>
<spring:import resource="classpath:spring-mule.xml"/>
<spring:import resource="classpath:applicationContext-persistence.xml"/>
<spring:bean id = "transactionFactory" class = "org.mule.module.spring.transaction.SpringTransactionFactory">
<spring:property ref="transactionManager" name=""></spring:property>
</spring:bean>
</spring:beans>
And add tansactionfactory ref to inboundEndpoint as shown below
<http:inbound-endpoint exchange-pattern="request-response"
address="http://localhost:8081/pos/addCustomer" doc:name="HTTP" >
<custom-transaction action="ALWAYS_BEGIN" factory-ref="transactionFactory"/>
</http:inbound-endpoint>
The full stream will consist of one transaction and includes dao classes
source to share