0 Replies Latest reply on Nov 15, 2011 9:06 AM by Valery Lezhebokov

    A SFSB as part of transaction

    Valery Lezhebokov Newbie

      Hi All,


      I observe an interesting behavior. I hava a SFSB with CMT which implements SessionSynchronization:



      @Stateful(name = "AImpl")


      public class AImpl implements A, SessionSynchronization {



          public void foo1() {

              System.out.println("from foo1");




          public void foo2() {

              System.out.println("from foo2");




          public void afterBegin() throws EJBException, RemoteException {

              System.out.println("afterBegin() invoked");




          public void afterCompletion(boolean arg0) throws EJBException, RemoteException {

              System.out.println("afterCompletion("+arg0+") invoked");




          public void beforeCompletion() throws EJBException, RemoteException {

              System.out.println("beforeCompletion() invoked");





      I also have a servlet which does exectly this:



              try {

                  Context ic = new InitialContext();

                  UserTransaction  userTransaction = (UserTransaction) ic.lookup("java:comp/UserTransaction");



                  A a = (A)ic.lookup("java:global/holiday-ear/holiday-ejb/AImpl!com.holiday.test.A");






              } catch (Exception e) {





      Now, when I call a.foo1() the bean becomes a part of the transaction and calling a.foo2() should throw an exception because of the new transaction being started by REQUIRES_NEW annotation. In other words I'm expecting to see this behaivior


      Enterprise JavaBeans 3.1


      Once a stateful session bean is a part of a transaction—whether it implements Session

      Synchronization or not—it cannot be accessed by any other transactional context. This

      is true regardless of whether the client tries to access the EJB with a different context

      or the EJB’s own method creates a new context. If, for example, a method with a transaction

      attribute of RequiresNew is invoked, the new transactional context causes an error

      to be thrown. Since the NotSupported and Never attributes specify a different transactional

      context (no context), invoking a method with these attributes also causes an




      But instead I see that when the a.foo2() is invoked the client transaction (the one started in the servlet) gets susspended and no exception is thrown!

      From the logs I can see that the bean "joins" transaction right before a.foo1() and "leaves" it when client transaction in commited (userTransaction.commit() in the servlet):



      14:20:42,656 INFO  [] afterBegin() invoked

      14:20:45,368 INFO  [] from foo1

      14:20:46,106 INFO  [] from foo2

      14:20:46,713 INFO  [] from foo2

      14:20:46,714 INFO  [] beforeCompletion() invoked

      14:20:46,714 INFO  [] afterCompletion(true) invoked



      Could anyone clerify why the exception is not thrown?





      PS: and it seems that I can actually remove the bean (calling @Remove method) while the bean is still in the transaction!

      PSS: in fact I can't remove it. The container doesn't throw the exception on the @Remove method invocation (and the method gets executed without problems), but the bean is there till the end of transaction.