Container-managed session bean NOT rolling back transactions...

Discussions

EJB programming & troubleshooting: Container-managed session bean NOT rolling back transactions...

  1. I tried using container-managed transactions with a stateless session bean (EJB 2.0) on WL6.1 for the first time, but with no luck. I attempted a very simple example in order to understand the concept and see it work, but the container doesn't seem to be "rolling back" after an SQLException is raised. I am simply inserting 2 rows of data. During the second insert, I am intentionally inserting NULL for a column that does not allow NULL in order to raise SQLException in the hope that the first insert will be rolled back, but it doesnt. Here is the method in my bean class:

    public void testCMTRX() throws SQLException {
     Context c = new InitialContext();
     DataSource ds = (DataSource)c.lookup( "jdbc/employee");
     Connection conn = ds.getConnection();
     Statement statement = conn.createStatement();
     statement.execute("INSERT INTO EMPLOYEE VALUES (500, 'Rick Connor'));
     statement.execute();

     Statement statement = conn.createStatement();
    /*NULL value is intentional in order to raise SQLException */
     statement.execute("INSERT INTO EMPLOYEE VALUES (NULL, 'Frank Morris'));
     statement.execute();
    }

    My deployment descriptor (ejb-jar.xml) for the ejb is as follows:

    <ejb-jar>
     <enterprise-beans>
      <session>
       <display-name>GoalJDAOTRX</display-name>
        <ejb-name>GoalJDAOTRX</ejb-name>
        <home>godriver.GoalJDAOTRXHome</home>
        <remote>godriver.GoalJDAOTRX</remote>
        <ejb-class>godriver.GoalJDAOTRXBean</ejb-class>
        <session-type>Stateless</session-type>
        <transaction-type>Container</transaction-type>
       </session>
      </enterprise-beans>
      <assembly-descriptor>
       <container-transaction>
        <method>
         <ejb-name>GoalJDAOTRX</ejb-name>
         <method-name>*</method-name>
        </method>
        <trans-attribute>Required</trans-attribute>
       </container-transaction>
      </assembly-descriptor>
    </ejb-jar>


    I must be missing something, but I cant figure out what it is. Am I missing something in the deplyoment descriptor?

    Thank You!

    SAF

  2. Hmmm, try this:

    public void testCMTRX(){
      try{
        Context c = new InitialContext();
        DataSource ds = (DataSource)c.lookup( "jdbc/employee");
        //anything you want...
      }catch(Exception ex){
        sessionContext.setRollbackOnly();
      }
    }

    It should be working. It works for me since, from WebLogic 5 to 6.1.
  3. Oh, let me tell you more about how exceptions and roll-backs.

    In EJB1.1, there are 2 levels of exceptions: system exceptions and appllication exceptions. System exceptions are RuntimeException and RemoteException. Others we regard them as application exceptions.

    When a system exception occurs, the container will roll back the transaction, log the exception, remove the bean instance, and throw a RemoteException.

    When an application exception occurs, transactions are not automatically rolled back. In fact, there are several "standard" application exceptions, like CreateException and DuplicateKeyException. You should read the spec for more details.

    The EJB container will regard the SQLException you have thrown from the method as an application exception, and thus the transaction won't be rolled back.
  4. yeah, you're right. I should read up on the spec before attempting container-managed transactions. But it seems the problem lay in SQLException, since it is NOT a system exception, the container did not rollback automatically.

    Thanks for the great advice guys. I'm sure I can solve the problem at this point.

    SAF