4 Replies Latest reply on Apr 24, 2013 9:12 PM by simondelfab

    Transacted web service

    simondelfab

      Originally posted on webservices forum (https://community.jboss.org/thread/224013) with minor modification.

       

      Hi,

       

      I have a web service method which reads off a JMS message off from websphere MQ and the client writes the response to a database. I want the reading of the message from the queue and the writing of the data to database to be performed as a single transaction. So I set about achieving this with WS-Atomic (and I also tried WS-BusinessActivity). I followed the samples [1] and got something working (minus the integration with Websphere) in my dev environment. When I tested in an environment which simulates the live environment, it failed to work because the server on which web service was being invoked couldn't communciate to the JBoss instance ("the client") calling the web service because the client was behind a firewall. On debugging and a bit research, I realise that (obviously) sychronous communication is necessary [2] for participant registration and coordination.

       

      So my first question is, is it possible to enable the communication back to the client to be performed over the connection established by the client to the server i.e. duplex communication like Web sockets? I doubt whether this would be possible given that HttpURLConnection that is probably being used by the client to make the call would not support Web sockets. I have considered creating a SSL tunnel from the "client" machine to the server, but this is not feasible at all deployments.

       

      Another question I wanted to ask is whether the client calling a transacted web service needs to be performed from within JBoss? I assume it has to because of the participant registration and coordination stuff.

       

      As an alternative solution to using WS-*, I implemented 2 web service methods (commit, rollback) which the client calls after writing the response to the database. On the server side, the read message web service method created a (transacted) session, read the message, spawned a thread (which had a reference to the JMS session), created a UUID as a transaction id and returned both the tx id and message back to the client. The spawned thread blocked (with timeout) and on receipt of either the commit and rollback web service methods, the thread was woken up and the JMS session was either committed or rolled back. Not exactly atomic, but it meant messages from the queue weren't lost and the possibility of duplicates was acceptable. I tested this with Hornet as the JMS implementation and it worked fine. But once I tried it with Websphere it didn't work because 1. the connection obtained from the factory was not transacted (despite using QueueConnection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE)) and 2. if I created a UserTransaction, it is bound to the current thread.

       

      I then looked into a solution where the transactional context is contained in a separate thread and I thought I came across the solution with javax.resource.spi.work.WorkManager, but this not available for general use in JBoss 7.1.1 [3].

       

      I have looked at using an EJB (3.1) asynchronous method [4] in conjunction with the above solution I have outlined, but I don't think that will work either.

       

      The situation I have encountered doesn't sound like a unique problem and I am certain there is solution or a practical work around this problem.  I don't particularly want to reinvent something that is most likely solved. I would appreciate some advice/feedback. Thanks.

       

      Regards,

      Simon

       

      [1] https://github.com/jboss-jdf/jboss-as-quickstart/tree/jdf-2.0.0.Final/wsat-simple

      [2] http://docs.jboss.org/jbosstm/5.0.0.M1/guides/xts-administration_and_development_guide/ch04.html

      [3] https://community.jboss.org/message/798227

      [4] http://satishgopal.wordpress.com/2011/04/24/ejb-3-1-asynchronous-methods/

        • 1. Re: Transacted web service
          paul.robinson

          Simon,

           

          I have a web service method which reads off a JMS message off from websphere MQ and the client writes the response to a database. I want the reading of the message from the queue and the writing of the data to database to be performed as a single transaction.

          Using WS-AT is a good choice for distributing the transaction over Web Services. However, you are going to find it difficult to tie up the lifecycle of that tranaction with that of the JTA transaction on the client and server side. I suggest you use the TXBridge technology in JBossTS to handle the bridging between these transactions. It's pretty easy to use, take a look at this quickstart if you are using JBoss 7.x https://github.com/jbosstm/quickstart/tree/4.17/TXBridge/demo and this one for AS8.x: https://github.com/jbosstm/quickstart/tree/master/XTS/jta-over-wsat

           

          When I tested in an environment which simulates the live environment, it failed to work because the server on which web service was being invoked couldn't communciate to the JBoss instance ("the client") calling the web service because the client was behind a firewall. On debugging and a bit research, I realise that (obviously) sychronous communication is necessary [2] for participant registration and coordination.

          Yes, this is expected. The Web Service transactions protocol can take some time to complete, which could cause sockets to time-out, if a synchronous communication pattern was used.

           

          However, you can configure the JBoss XTS client to use a synchronous communication with the transaction coordinator. This is a JBoss XTS only feature, so you will need to be using JBoss XTS for your client and coordinator. You may also need to increase the socket-timeout to ensure that the socket is kept open long enough for the transaction protocol to complete. Assuming this is not a problem, this is what you should do:

           

          1. You need to configure the client to use a remote coordinator. This is because the communication between the coordinator and participants will still be asynchronous. Therefore you should use a coordinator that your participants can contact. Maybe pick the server running your service. You can configure this by setting the xts-environment url in standalone-xts.xml:

           

          <xts-environment url="http://${jboss.bind.address:127.0.0.1}:8080/ws-c11/ActivationService"/>
          

           

           

          2. Next you need to configure the XTS client to call the synchronous endpoint on that coordinator, rather than the asynchronous endpoint, which is used by default. This is a bit tricker to set, as we don't yet have an easily accesible configuration option for this. You need to edit the xts-properties.xml file that is in the root of the following jar:

           

          $JBOSS_HOME/modules/org/jboss/xts/main/jbossxts-*.jar

           

          You need to change this line:

           

           

          <entry key="org.jboss.jbossts.xts11.wsat.UserTransaction">com.arjuna.mwlabs.wst11.at.remote.UserTransactionImple</entry>
          

           

          to:

           

          <entry key="org.jboss.jbossts.xts11.wsat.UserTransaction">com.arjuna.mwlabs.wst11.at.remote.UserTransactionStandaloneImple</entry>
          

           

          Once you have made this change, I'd recommend getting the file out of the jar again, to make sure the change has stuck. I've had problems where certain zip file viewers have allowed me to edit text files, but the changes have not been written back.

           

          This should be all you need to do. If you have any problems with this, let me know and I'll help you further,

           

          Paul.

          1 of 1 people found this helpful
          • 2. Re: Transacted web service
            simondelfab

            Thanks Paul. I will have a go at synchronous communication with the transaction manager later in the week and let you know how I go.

             

            Re changes to $JBOSS_HOME/modules/org/jboss/xts/main/jbossxts-*.jar: Your suggested changes didn't come through in the post.

            • 3. Re: Transacted web service
              paul.robinson

              Simon,

               

              I've fixed the rendering of the XML in the post.

               

              Paul.

              • 4. Re: Transacted web service
                simondelfab

                Thanks.