10 Replies Latest reply on Sep 22, 2008 6:28 PM by gjeudy

    Transactions, Checked and Unchecked Exceptions, Rollback

    asiandub

      hello,


      I have a (understanding?) problem with transactions, checked and unchecked exceptions and rollbacks.


      this is what happens:
      I have a controller, which is a seam-component (and not an EJB). The controller method A calls a SFSB-method B, which itself calls another SFSP-method C. C does some business-logic which causes a checked exception to be thrown. B catches the checked exception.


      this is A


      (component)
      public void aMethod() {
           try {
                SFSB1.bMethod()
           } catch (RuntimeException E) {
           doSomething();
           }
      }




      this is B:


      (SFSB1)
      public void bMethod() {
           try {
                SFSB2.cMethod()
           } catch (CheckedException E) {
                throw new UncheckedException()
           }
      }




      this is C:


      (SFSB2)
      public void cMethod() throws CheckedException{
           doStuff()
           throw new checkedException()
      }





      What i want are two things:


      - the transaction has to be rolled back


      - B throws an unchecked exception, which A can either catch or not. The first is supposed to result in some kind of specific error-page forwarding (the registration process failed), the latter in a general error forwarding (oops, we had a problem).


      What i get instead is the following:


      - B catches the checked exception and throws the unchecked exception.

      - the transaction gets rolled back (because of the unchecked exception?)
      - C is unable to catch the unchecked exception, instead it gets a javax.ejb.EJBTransactionRolledbackException with my unchecked exception as root cause.


      okay, i COULD catch the EJB-Exception, but this is not what i want.


      can anybody help / clarify?


      many thanks,
      jan


        • 1. Re: Transactions, Checked and Unchecked Exceptions, Rollback
          asiandub

          just to make things more clear for the reader in a hurry:


          I cannot catch the exception from B in A. No matter what I try, all I get is an EJBTransactionRolledbackException ...


          :-(

          • 2. Re: Transactions, Checked and Unchecked Exceptions, Rollback
            accless

            Could u clearify your problem/question? I dont understand your point!

            • 3. Re: Transactions, Checked and Unchecked Exceptions, Rollback
              asiandub

              Sorry. That forum really really (really!) requires and edit function.



              Okay - have look at this posting. Here is my problem / question:




              • (1) throws an exception which (2) is unable to catch. - why?




              • I want the Transaction to be rolled back until (2). - How?






              many thanks,


              jan


              ....................


              this is A


              (component)


              public void aMethod() {
                   try {
                        SFSB1.bMethod()
              (2)     } catch (MyUncheckedException E) {
                   doSomething();
                   }
              }




              this is B:


              (SFSB1)


              public void bMethod() {
                   try {
                        SFSB2.cMethod()
                   } catch (CheckedException E) {
              (1)          throw new MyUncheckedException()
                   }
              }




              this is C:


              (SFSB2)


              public void cMethod() throws CheckedException{
                   doStuff()
                   throw new checkedException()
              }


              • 4. Re: Transactions, Checked and Unchecked Exceptions, Rollback
                accless

                public void aMethod() {
                     try {
                          SFSB1.bMethod()
                (2)     } catch (MyUncheckedException E) {
                     doSomething();
                     }
                }



                As far as i understand, the exception thrown in bean 1 is not catched in your bean 2,richt? Try to catch Exception insteadof MyUncheckedException

                • 5. Re: Transactions, Checked and Unchecked Exceptions, Rollback
                  gjeudy

                  Can you explain your transaction propagation rules? Are you using REQUIRED which means A,B,C are all using the same transaction that was started by the call to A ?


                  A little reading on exception behavior with EJBs might be in order here. The EJB container will always wrap unchecked exceptions in it's own javax.ejb.EJBException flavor. If you want to avoid this you will need to define your unchecked exception as an application exception.


                  You can use

                  @ApplicationException(rollback=true)

                  on your uncheckedException, when the EJB container sees this it will not wrap your exception and let it pass to the caller,
                  rollback=true

                  will cause the EJB to rollback the transaction. By default an application exception does not cause a rollback.

                  • 6. Re: Transactions, Checked and Unchecked Exceptions, Rollback
                    asiandub

                    Hello Rene,


                    thanks for answering. :-)


                    Catching Exception is absolutely not what I want. I just want to catch MyUncheckedException, everything else is something unplanned and not supposed to be caught here...


                    Jan

                    • 7. Re: Transactions, Checked and Unchecked Exceptions, Rollback
                      asiandub

                      Hello Guillaume,


                      thanks a lot for answering.


                      my transaction propagation rules are set to default. This means that - in my understanding - the transaction is started with the call to B (and not in A as you wrote), because B is in a SFSB. C joins the transaction.


                      The default seam behaviour is to rollback the transaction if the exception is unchecked, and to leave the transaction untouched if the exception is checked. So (1) causes the transaction to get rolled back - that's exactly what I want.


                      To your proposal:


                      I am sure I could make MyUncheckedException checked. But then the transaction would not be rolled back automatically. Furthermore the caller would have to catch / declare it in any case, which is something I dont want him to do.


                      Why? Because MyUncheckedException is a wrapper for any kind of exception that can occur at SFSB-Level, and normally there is absolutely no need that the controller tier is aware of it (read: nothing a controller could do but showing an error page).


                      Let me narrow it down:


                      If MyUncheckedException is thrown from the SFBS tier, I want two things to happen:




                      • The transaction to get rolled back.

                      • The ability for the controller to catch MyUncheckedException or the possiblity to annotated an error page view id with this exception.




                      I do not want to have my exception being wrapped automagically.


                      Se(a)ms like there is not much i can do about it, eh?


                      Cheers from Berlin,
                      Jan




                      • 8. Re: Transactions, Checked and Unchecked Exceptions, Rollback
                        gjeudy

                        Hi Jan,


                        I'm not sure you fully read my initial reply.


                        - If you want any control on the transaction handling you must prevent the exception wrapping. The only way to achieve this is to declare your unchecked exception likeso.


                        @ApplicationException(rollback=true)
                        public class MyUncheckedException extends RuntimeException {
                         ...
                        }
                        



                        Thats it, the transaction spanning SFSB B and C will get rolled back, moreover you can now define exception handling in pages.xml likeso:


                        <exception class="a.b.c.MyUncheckedException">
                                  <redirect view-id="/exception/exception.xhtml">
                                       <message severity="error">
                                            Unexpected exception occurred.               </message>
                                  </redirect>
                             </exception>
                        

                        • 9. Re: Transactions, Checked and Unchecked Exceptions, Rollback
                          asiandub

                          Hello Guillaume,


                          thanks for getting back to me.


                          Annotating the exception as you proposed did have no effect.


                          Which kind of matches my understanding - a unchecked exception is already rolling back the transaction, so rollback = true has no extra-effect. (2) is still unable to catch the exception.


                          If I'm playing with the switch and set it to rollback=false, the catch works fine. but of course the transaction isn't rolled back :-(


                          Having said this, i have to admit that your proposal worked fine in another situation with different beans in a different project. Even though after one hour of investigation I'm still unable to tell the difference, this smells like a configuration issue.


                          :-(


                          Enough for today (GMT),


                          many thanks again,


                          Jan

                          • 10. Re: Transactions, Checked and Unchecked Exceptions, Rollback
                            gjeudy

                            Is the exception class deployed inside your EAR file as an EAR lib or ejb-module ? Are you using JBoss 4.2.2 ?


                            I know the uncheckedexceptions are implicitely rolled backed. What i'm saying is that the EJB container will wrap your exception if you don't define it as an ApplicationException. i.e. by default all checked exceptions are application exceptions.


                            So if you don't specify

                            rollback=true

                            on your applicationexception it will not rollback.


                            This is an EJB3 spec feature so if annotating your exception has no effect I advise that you check your configuration to make sure that the container reads your annotation and handles it normally.