3

I am new to mule. I have a spring-hibernate mule setup. Suppose there are 3 webservice.Aim is to invoke all those webservice in a mule flow so that all 3 will be in a transaction. so that suppose if 3rd webservice fails then the previous 2 will be rolled back automatically.

Here is my code snippet what 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>

My: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.Thanks

Rajesh
  • 2,934
  • 8
  • 42
  • 71

2 Answers2

1

By seeing your question what I understood is your trying to make 3 web-service calls and you want to make all three calls in a single transaction.

As you are making a call to another system (Web-service in your case) you don't have control to maintain the transaction.

In your case you can use a Scatter gather router to call three web-services if any route(web-service call) is failed it will throw CompositeRoutingException, you can very well catch this exception in your catch exception strategy.

In your catch exception strategy you need to do the roll back activities (make another web-service call or db call which will fulfill your rollback requirement ).

ivan.mylyanyk
  • 2,051
  • 4
  • 30
  • 37
0

As per my understanding, you have a three or more webservices calls and some db operations. you want to rollback if any service call fails.

Write a spring bean as below for SpringTransactionFactory and set transationManager property (ref from your applicationContext-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 a tansactionfactory ref to inboundEndpoint as 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>

Complete flow will be in single transaction and inclouding dao classes

Namus G
  • 25
  • 10