7 Replies Latest reply on Feb 20, 2004 6:54 PM by razvan_t

    Big problem with EJBs of Web Tier

    ccsaxton

      I have found a problem that could cause you a serious headache...please flame me if I am wrong...

      Some browsers will (mostly on a windows platform) cut short a connection request with an application server...Sometimes it is the server that can do this but whether the server or client closes the connection you don't really have any control over it! And here is the catch!!! Some browsers will then resend the POST/GET data without your intervention...what a headache...

      The problem with this is the following!

      1. Client posts data to servlet container over http.

      2. Servlet reads client data from form details passed as arguments and calls an EJB with the details...the EJB stores the data to a table the EJB also returns a confirmation string which is to be sent back to the calling client wrapped up in some pretty html layout...

      3. At point 2, at the end of the call to the EJB..."""THE TRANSACTION ENDS AND THE DATA IS COMMITTED TO THE DATABASE SINCE THE EJB TRANSACTION HANDLING IS HANDLED BY THE CONTAINER!!!!"""

      4. You now wrap up you request and return the data via the socket to the calling client...

      5. Midway through this IE or the server throw a wobbly and close the connection...

      what happens next can be one of 2 things...

      6. in some cases you will get an error returned to the browser but in other cases the browser will resend the request, especially if it was the browser that closed the connection in the first place! You can see where I am going with this can you not...repeat steps 2 onwards and you get 2 sets of data posted to the database...

      7. The client will only receive one result page and will not be aware that the post as gone twice. I must admit that I have only observed this behaviour with IE but since it is on 95% of boxes outthere then It is cause for concern!!

      How do you get round this...All I can think of is that you would have to abandon using an EJB and start a user transaction from within the servlet. The transaction can then complete on a finally clause after the socket connect closes finishing the request response...if the connection goes down you get an exception which you can the use to roll back the transaction...

      ANY IDEAS!!!

      The problem will also occur if you call EJBs over SOAP/XMLRPC...as anyone else seen this issue...I have noticed similar posts on the web where people are getting double posts using JSP....and they are unable to explain it since they have disabled client side submit buttons...etc.

      This is a fundimental flaw with using EJBs over a web container...can you setup the web container to initiate the transaction??? If not, then what?

        • 1. Re: Big problem with EJBs of Web Tier
          marc.fleury

          It is a very good point as far as I can tell. I don't know why anyone didn't see it before. Maybe we are missing something (on the data being commited on a return)

          One of things we are doing in JBoss 4.0 is isolate the TX demarcation as an aspect so that the tx demarcation can be done on ANY POJO (not just EJB). With that we could simply add that interceptor on the servlet method in the TOMCAT layer and provide you with the semantic you need there.

          • 2. Re: Big problem with EJBs of Web Tier
            pilhuhn

            I don't get your point. You can start a UserTransaction from the servlet
            and still use EJBs.
            In any case, your software should catch double invocations if this is a
            problem for your business logic. The app server can't know if this is
            intended or not.

            • 3. Re: Big problem with EJBs of Web Tier
              ccsaxton

               

              "pilhuhn" wrote:
              I don't get your point. You can start a UserTransaction from the servlet
              and still use EJBs.
              In any case, your software should catch double invocations if this is a
              problem for your business logic. The app server can't know if this is
              intended or not.


              You can start a user transaction from within a servlet and still use an EJB but the EJB container will start its own transaction and commit the data...I am sorry but it is a "very big problem!".

              1. The client does not get an error thrown back since the browser will just re-request the post with the same data...This can and does happen with IE.

              2. If the EJB method is performing a database update then it will commit the update after the method exits...you then might want to send data back through the servlet...the problem here occurs because the socket goes down but you have already performed the update so you cannot rollback!...

              3...Unknown to the user IE will attempt to re-post the data...second time it may work (This is not a problem with IE it could be anything!) but now you have 2 sets of data or 2 update requests performed and not one!

              I re-iterate my statement that "unless you can put the EJB logic in the same transaction that is started in the servlet" using EJBs over a WebTier will not be transaction safe...Do you know how to run an EJB so that the transaction begins in the web tier and will your solution work for all J2ee application servers?

              • 4. Re: Big problem with EJBs of Web Tier
                camel

                Would it help if you made your POST operation idempotent? (i.e., doing it more than once has no more effect than doing it once).

                • 5. Re: Big problem with EJBs of Web Tier

                   

                  "ccsaxton" wrote:

                  You can start a user transaction from within a servlet and still use an EJB but the EJB container will start its own transaction and commit the data...


                  The EJB container will use the existing transaction associated with the thread unless you explicitly configure it to start a new transaction with RequiresNew.

                  "ccsaxton" wrote:

                  I re-iterate my statement that "unless you can put the EJB logic in the same transaction that is started in the servlet" using EJBs over a WebTier will not be transaction safe...Do you know how to run an EJB so that the transaction begins in the web tier and will your solution work for all J2ee application servers?


                  UserTransaction will do this.


                  • 6. Re: Big problem with EJBs of Web Tier
                    rad

                    what I do if I have a long DB transaction is stream a bit of javascrip to the browser and update the status bar. this keeps the http connection open. I have had http connections open for helf an hour. Of course you will need to pool your beans otherwise its a one user application

                    • 7. Re: Big problem with EJBs of Web Tier
                      razvan_t

                      Hi ccsaxton.

                      If you are still interested in solving your problem, you might take a look on this article:
                      http://www.javaworld.com/javaworld/javatips/jw-javatip136.html

                      Even if you don't use struts, it might give you an idea about what can be done.
                      I, personally, find it very valuable.

                      Razvan