Help coderanch get a
new server
by contributing to the fundraiser
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Devaka Cooray
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Carey Brown
  • Mikalai Zaikin
Bartenders:
  • Lou Hamers
  • Piet Souris
  • Frits Walraven

Caller bean is discarded when callee throws EJBException?

 
Bartender
Posts: 2438
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Refering to p.386, table 15,
consider this scenario:

if Bean A has method a() with transaction type attribute = required,
Bean B has method b() with transaction type attribute = requires_new,
a() invokes b().
Bean A is the client of Bean B.

if b() throws EJBException , bean B's transaction is rolled back and bean B is discarded.
Will bean A be discarded also?
Will bean A's transaction marked rollback?

The table says

From client's view, if the client executes in a transaction, the client's transaction may or may not be marked for rollback.


This table does not mention if the client , which is also a bean, will be discarded.
 
Himai Minh
Bartender
Posts: 2438
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let me answer my own question.
If bean B throws a system exception and the caller, bean A catches the exception, bean B is discarded and bean A is not discarded. (I can see bean A is not discarded when I shut down the container, the @PreDestroy method of bean A is called.) The transaction of bean A is not rollback.

If bean B throws a system exception and the caller bean A does not catch the exception, bean B and A will be discarded. And the transaction of bean A is marked for rollback.
 
Creator of Enthuware JWS+ V6
Posts: 3412
320
Android Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Himai,

Good question ! and the answer is: it depends

Normally you want a method anotated with REQUIRES_NEW not to affect the current transaction. Coding will be something likes this:

In this case BeanA is not affected by the transaction rollback and the EJBException inside beanB.

Now if you don't catch the exception, BeanA.methodA() will throw a System Exception (i.e. EJBException). Normal rules apply:
  • Exception will be logged by the container
  • EJB will be discarded
  • Transaction will be rollbacked (or marked for rollback: setRollBackOnly() if transaction was started by another client, let's say initialClient)
  • Container will throw EJBException to the initialClient or EJBTransactionRollbackException to the initialClient (if transaction was started by initialClient)


  • Does this clear up your doubts?

    Regards,
    Frits
     
    Himai Minh
    Bartender
    Posts: 2438
    13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    For everyone's reference as this seems very important for the exam,
    If these three conditions hold:

    1. bean B 's b() method's transaction attribute type is also required
    2. b() throws a system exception
    3. a() catches the exception,

    these will happen:
    1. a() catches the exception wrapped by EJBTransactionRollbackLocalException
    2. bean B is discarded.
    3. bean A is not discarded.
    4. a()'s transaction is marked for rollback.


    It concludes that if the caller bean (eg bean A in this case) catches the system exception thrown by the callee bean, the caller bean is not discarded.
    If the callee's transaction is a new one, the caller's transaction won't be rollbacked.
    If the callee's transaction is the same as the caller's , the caller's transaction will be rollbacked.
     
    Himai Minh
    Bartender
    Posts: 2438
    13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi, Frits. Thanks for your example.
    A similar question was asked in Enthuware.
    I tried with a similar example:



    Warning: A system exception occurred during an invocation on EJB BeanB method public void com.ivan.scbcd6.BeanB.methodB()
    javax.ejb.EJBException
    ...
    Caused by: java.lang.RuntimeException: run time exception from b
    ...

    Info: A transaction rollback ?false

    Info: Server shutdown initiated
    Info: pre destroy method called for Bean A.



    As we can see, the transaction of A is not marked for rollback. When I shut down the server, the @PreDestroy of Bean A is called.
     
    Himai Minh
    Bartender
    Posts: 2438
    13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator



    In this case, both bean A and B are discarded. @PreDestroy methods of both beans are not called when the container is shut down.


    A system exception occurred during an invocation on EJB BeanB method public void com.ivan.scbcd6.BeanB.methodB()
    javax.ejb.EJBException
    ....
    Caused by: java.lang.RuntimeException: run time exception from b
    ...

    Warning: A system exception occurred during an invocation on EJB BeanA method public void com.ivan.scbcd6.BeanA.methodA()
    javax.ejb.EJBException
    ....
    Caused by: java.lang.RuntimeException: run time exception from b
    ...

    Warning: StandardWrapperValve[OtherServlet]: PWC1406: Servlet.service() for servlet OtherServlet threw exception
    javax.ejb.EJBException
    ...
    Caused by: java.lang.RuntimeException: run time exception from b
    ...

     
    Himai Minh
    Bartender
    Posts: 2438
    13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    This time, bean B and Bean A's transaction attributes are both REQUIRED and Bean A catches Bean B's exception:




    A system exception occurred during an invocation on EJB BeanB method public void com.ivan.scbcd6.BeanB.methodB()
    javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
    ...
    Caused by: java.lang.RuntimeException: run time exception from b
    ...
    Info: A transaction rollback ?true
    Info : pre destroy method called for Bean A.



    The exception from bean B is wrapped by TransactionRolledBackLocalException and Bean B is discarded. But Bean A is not discarded.
     
    Himai Minh
    Bartender
    Posts: 2438
    13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Tried with bean A and B's transaction attributes are REQUIRED, but this time bean A does not catch the exception from bean B:


    A system exception occurred during an invocation on EJB BeanB method public void com.ivan.scbcd6.BeanB.methodB()
    javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
    ....
    Caused by: java.lang.RuntimeException: run time exception from b
    ....

    Warning: A system exception occurred during an invocation on EJB BeanA method public void com.ivan.scbcd6.BeanA.methodA()
    javax.ejb.EJBTransactionRolledbackException
    ....
    Caused by: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
    ...
    Caused by: java.lang.RuntimeException: run time exception from b
    ...

    Warning: StandardWrapperValve[OtherServlet]: PWC1406: Servlet.service() for servlet OtherServlet threw exception
    javax.ejb.EJBTransactionRolledbackException
    ...
    Caused by: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
    ...
    Caused by: java.lang.RuntimeException: run time exception from b
    ...




    Bean A got a EJBTransactionRollbackException that wraps the EJBTransactionRollbackLocalException, which wraps the runtime exception.
    When the EJB container is shut down, no @PreDestroy method is called. Bean A and B are discarded.
     
    Consider Paul's rocket mass heater.
    reply
      Bookmark Topic Watch Topic
    • New Topic