-->

Wso2Dss Box_Carring not working in WSO2esb4.8.0

2020-04-14 20:00发布

问题:

I am working with wso2dss3.0.1 and wso2esb4.8.0.I wish to work with Transactions for that i enabled box_carying in wso2dss and its working fine.Means i wish insert the data into 2 tables if 2nd table failed my first table also need to rollback.This functionality working in wso2dss.While i am calling same service using wso2esb that time transaction rollback is not working box_carying is not working fine my configuration is like this

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="TransactionProxy"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <log level="full">
            <property name="M1" value="*************HITTING Transaction PROXY*************"/>
         </log>
         <property name="OUT_ONLY" value="true"/>
         <property name="companycode" expression="//companycode/text()"/>
         <property name="companyname" expression="//companyname/text()"/>
         <property name="clientcode" expression="//clientcode/text()"/>
         <property name="clientname" expression="//clientname/text()"/>
         <payloadFactory media-type="xml">
            <format>
               <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                                 xmlns:dat="http://ws.wso2.org/dataservice">
                  <soapenv:Header/>
                  <soapenv:Body/>
               </soapenv:Envelope>
            </format>
            <args/>
         </payloadFactory>
         <log level="full">
            <property name="M2" value="*************HITTING Transaction PROXY*************"/>
         </log>
         <header name="Action" value="urn:begin_boxcar"/>
         <callout serviceURL="http://192.168.1.201:9764/services/Transaction/begin_boxcar"
                  action="urn:begin_boxcar">
            <source type="envelope"/>
            <target xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                    xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                    xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
         </callout>
         <payloadFactory media-type="xml">
            <format>
               <p:insertinto_mclient_OP xmlns:p="http://ws.wso2.org/dataservice">
                  <xs:clientcode xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:clientcode>
                  <xs:clientname xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:clientname>
                  <xs:createdbyid xmlns:xs="http://ws.wso2.org/dataservice">-1</xs:createdbyid>
                  <xs:modifiedbyid xmlns:xs="http://ws.wso2.org/dataservice">-1</xs:modifiedbyid>
               </p:insertinto_mclient_OP>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('clientcode')"/>
               <arg evaluator="xml" expression="get-property('clientname')"/>
            </args>
         </payloadFactory>
         <header name="Action" value="urn:insertinto_mclient_OP"/>
         <callout serviceURL="http://192.168.1.201:9764/services/Transaction/"
                  action="urn:insertinto_mclient_OP">
            <source xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                    xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                    xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
            <target xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                    xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                    xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
         </callout>
         <payloadFactory media-type="xml">
            <format>
               <p:insertinto_mcompany_OP xmlns:p="http://ws.wso2.org/dataservice">
                  <xs:companycode xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:companycode>
                  <xs:comapnyname xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:comapnyname>
                  <xs:createdbyid xmlns:xs="http://ws.wso2.org/dataservice">-1</xs:createdbyid>
                  <xs:modifiedbyid xmlns:xs="http://ws.wso2.org/dataservice">-1</xs:modifiedbyid>
                  <xs:clientid xmlns:xs="http://ws.wso2.org/dataservice">-1</xs:clientid>
               </p:insertinto_mcompany_OP>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('companycode')"/>
               <arg evaluator="xml" expression="get-property('companyname')"/>
            </args>
         </payloadFactory>
         <log level="full">
            <property name="M5" value="**************hitting2nd dss*****"/>
         </log>
         <header name="Action" value="urn:insertinto_mcompany_OP"/>
         <callout serviceURL="http://192.168.1.201:9764/services/Transaction/"
                  action="urn:insertinto_mcompany_OP">
            <source xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                    xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                    xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
            <target xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                    xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                    xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
         </callout>
         <payloadFactory media-type="xml">
            <format>
               <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                                 xmlns:dat="http://ws.wso2.org/dataservice">
                  <soapenv:Header/>
                  <soapenv:Body/>
               </soapenv:Envelope>
            </format>
            <args/>
         </payloadFactory>
         <log level="full">
            <property name="M3" value="*************HITTING Transaction PROXY*************"/>
         </log>
         <header name="Action" value="urn:end_boxcar"/>
         <callout serviceURL="http://192.168.1.201:9764/services/Transaction/end_boxcar"
                  action="urn:end_boxcar">
            <source type="envelope"/>
            <target xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                    xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                    xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
         </callout>
         <log level="full">
            <property name="M4" value="*************HITTING Transaction PROXY*************"/>
         </log>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <description/>
</proxy>

If i send correct values to db those values are storing in tables well but if i send wrong data into second table even though my 1st table storing data 2nd is going wrong.Here Box_carrying is not happening is this version error something else.where as from wso2dss try-it tool transaction working fine then y not from wso2esb sides i followed this link enter link description here enter link description here Thanks in Adv..

回答1:

Your you are not doing your DSS operations in the same session.

DSS uses the JSESSIONID cookie to identify sessions. You need to grab that cookie from the begin_boxcar call and in turn send the cookie along with the rest of the DSS calls that you wish to perform in the same transaction.

Finally you will need to send the same cookie in the call to end_boxcar or abort_boxcar, whichever you end up calling.

After your call to a begin_boxcar operation in a DSS service you can access the cookies set by the service through transport properties:

<property name="setCookieHeader" expression="$trp:Set-Cookie" action="set"/>

After you have the cookie in a Synapse message context property you can use a scripting language such as Groovy or JavaScript to parse the actual value from the cookie.

Any subsequent DSS calls that should be in the same boxcarring session must send the cookie to the DSS service. You can have Axis2 send the cookie by setting it to a transport property (analogous to HTTP headers in this case):

<property name="Cookie" expression="$ctx:jsessionIdCookie" action="set" scope="transport" />


回答2:

There is a workaround, use request_box to wrap multiple sql non-query operation in a single request to avoid using session. If any sql in the request fails, the whole request will be rollback.

First you need a mysql database named MyDB with a user named root whose password is root and a Postgresql database also named MyDB with a user named postgres whose password is root. Then create a table named customer in both databases:

    CREATE TABLE customer (
        cust_id int(11) NOT NULL,
        name varchar(255) NOT NULL,
        PRIMARY KEY (`cust_id`)
    );

The sample inserts a record into mysql, then inserts two records with the same cust_id into postgres which causes an error, so the whole transaction will be rolled back and you will not see the record inserted into mysql.

Below is my proxy service definition:

    <?xml version="1.0" encoding="UTF-8"?>
    <proxy xmlns="http://ws.apache.org/ns/synapse" name="MyTransactionProxy" 
        startOnLoad="true" statistics="disable" trace="disable" transports="http,https">
        <target>
            <inSequence>
                <property expression="//id/text()" name="id"/>
                <property expression="//name/text()" name="name"/>
                <payloadFactory media-type="xml">
                    <format>
                        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                          xmlns:dat="http://ws.wso2.org/dataservice">
                            <soapenv:Header/>
                            <soapenv:Body>
                                <dat:request_box>
                                    <dat:my_insert>
                                        <dat:id>$1</dat:id>
                                        <dat:name>$2</dat:name>
                                    </dat:my_insert>
                                    <dat:pos_insert>
                                        <dat:id>$1</dat:id>
                                        <dat:name>$2</dat:name>
                                    </dat:pos_insert>
                                    <dat:pos_insert>
                                        <dat:id>$1</dat:id>
                                        <dat:name>$2</dat:name>
                                    </dat:pos_insert>
                                </dat:request_box>
                            </soapenv:Body>
                        </soapenv:Envelope>
                    </format>
                    <args>
                        <arg evaluator="xml" expression="get-property('id')"/>
                        <arg evaluator="xml" expression="get-property('name')"/>
                    </args>
                </payloadFactory>
                <callout action="urn:request_box" serviceURL="http://longqinsi:8280/services/DTPDS">
                    <source xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" 
                        xmlns:s12="http://www.w3.org/2003/05/soap-envelope" 
                        xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
                    <target xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" 
                        xmlns:s12="http://www.w3.org/2003/05/soap-envelope" 
                        xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
                </callout>
            </inSequence>
            <outSequence>
                <send/>
            </outSequence>
        </target>
        <description/>
    </proxy>

My data service is defined as below:

    <?xml version="1.0" encoding="UTF-8"?>
    <data disableStreaming="true" enableBoxcarring="true" enableDTP="true" name="DTPDS">
        <config id="pos_ds">
            <property name="org.wso2.ws.dataservice.xa_datasource_class">org.postgresql.xa.PGXADataSource</property>
            <property name="org.wso2.ws.dataservice.xa_datasource_properties">
                <property name="ServerName">localhost</property>
                <property name="PortNumber">5432</property>
                <property name="DatabaseName">MyDB</property>
                <property name="User">postgres</property>
                <property name="Password">root</property>
            </property>
        </config>
        <config id="my_ds">
            <property name="org.wso2.ws.dataservice.xa_datasource_class">com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</property>
            <property name="org.wso2.ws.dataservice.xa_datasource_properties">
                <property name="URL">jdbc:mysql://localhost:3306/MyDB</property>
                <property name="User">root</property>
                <property name="Password">root</property>
            </property>
        </config>
        <query id="pos_q" useConfig="pos_ds">
            <sql>INSERT INTO customer VALUES(?,?)</sql>
            <param name="id" sqlType="INTEGER"/>
            <param name="name" sqlType="STRING"/>
        </query>
        <query id="my_q" useConfig="my_ds">
            <sql>INSERT INTO customer VALUES(?,?)</sql>
            <param name="id" sqlType="INTEGER"/>
            <param name="name" sqlType="STRING"/>
        </query>
        <operation disableStreaming="true" name="pos_insert" returnRequestStatus="true">
            <call-query href="pos_q">
                <with-param name="id" query-param="id"/>
                <with-param name="name" query-param="name"/>
            </call-query>
        </operation>
        <operation disableStreaming="true" name="my_insert" returnRequestStatus="true">
            <call-query href="my_q">
                <with-param name="id" query-param="id"/>
                <with-param name="name" query-param="name"/>
            </call-query>
        </operation>
    </data>