6 Replies Latest reply on Nov 25, 2008 9:12 AM by Carlo de Wolf

    UserTransactedStartedListener is not implemented in EJB3

    Adrian Brock Master

      This relates to JBCTS-599 but I can explain it without reference to that.

      There is a little known feature in JavaEE called lazy transaction enlistment.
      It basically works with the UserTransaction where you retrieve a connection
      before starting the transaction and then ut.begin() enlists the connection.

      // BMT EJB(3) method
      public void doSomething()
      {
       DataSource ds = ...
       Connection c = ds.getConnection(); // Not enlisted in transaction, there isn't one
       UserTransaction ut = ...
       ut.begin(); // the connection is enlisted in the transaction
      }
      


      It even works across multiple transactions

      public void doSomething()
      {
       DataSource ds = ...
       Connection c = ds.getConnection(); // Not enlisted in transaction, there isn't one
       UserTransaction ut = ...
       ut.begin(); // the connection is enlisted in the transaction
       ut.commit(); // connections is unenlisted
       ut.begin(); connection is enlisted in the new/different transaction
      }
      


      The problem is that EJB3 is not firing the transaction started events
      from its user transaction.

      Compare EJB2/EJB3:
      org.jboss.ejb.EnterpriseContext/org.jboss.ejb3.tx.UserTransactionImpl

      
       public void begin()
       throws NotSupportedException, SystemException
       {
       TransactionManager tm = con.getTransactionManager();
      
       int oldTimeout = -1;
       if (tm instanceof TransactionTimeoutConfiguration)
       oldTimeout = ((TransactionTimeoutConfiguration) tm).getTransactionTimeout();
      
       // Set the timeout value
       tm.setTransactionTimeout(timeout);
      
       try
       {
       // Start the transaction
       tm.begin();
      
       // HERE!!!!!!!!!!!!! notify checked out connections
       if (tsl != null)
       tsl.userTransactionStarted();
      
       Transaction tx = tm.getTransaction();
       if (trace)
       log.trace("UserTx begin: " + tx);
      


      In fact, if you compare the two classes you'll see that the EJB3
      user transaction is incomplete in other ways (such as resetting
      the transaction timeout after the begin).