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:

       

      {code}

      @Stateful(name = "AImpl")

      @TransactionManagement(TransactionManagementType.CONTAINER)

      public class AImpl implements A, SessionSynchronization {

       

          @TransactionAttribute(TransactionAttributeType.REQUIRED)

          public void foo1() {

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

          }

       

          @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

          public void foo2() {

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

          }

       

          @Override

          public void afterBegin() throws EJBException, RemoteException {

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

          }

       

          @Override

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

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

          }

       

          @Override

          public void beforeCompletion() throws EJBException, RemoteException {

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

          }

      }

      {code}

       

      I also have a servlet which does exectly this:

       

      {code}

              try {

                  Context ic = new InitialContext();

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

       

                  userTransaction.begin();

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

       

                  a.foo1();

                  a.foo2();

       

                  userTransaction.commit();

              } catch (Exception e) {

                  e.printStackTrace();

              }

      {code}

       

      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

      {quote}

      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

      error.

      {quote}

       

      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):

       

      {quote}

      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

      {quote}

       

      Could anyone clerify why the exception is not thrown?

       

      Thanks,

      Valery

       

      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.