EJB programming & troubleshooting: Container Managed Transacation and JDBC calls from Session Beans

  1. When doing a JDBC call from a session bean, does it make sense to have a container managed transaction?

    Does having this, when the JDBC fails, throw an EJB exception?

    Therefore do you wrap your call to JDBC in a try catch to catch the EJBExcetion?

  2. I dont think an EJBException would be thrown, when a JDBC call fails. Let me know if it does.

    You should use Bean Managed Transaction and UserTransaction.Rollback when an JDBC call fail.

  3. Rephrasing the question, does a session bean having a container managed transaction throw an EJBException on failure. Even if a JDBC call failed from within the bean.

    Are all exception from the bean wrapped in a EJBException?
  4. Any system level exception thrown in enterprise beans is wrapped as a java.rmi.RemoteException and thrown by the container to a remote client, or as a javax.ejb.EJBException thrown to a local client. Wrapping your JDBC calls in a try/catch block is a good idea, but instead of catching the EJBException, catch SQLException and/or RunTimeException and depending on what you want to do, re-throw an EJBException or your own application Exception or mark the TX as rollback only. Any standard EJB text (especially Richard Monson-Haefel's book and Wrox's Pro EJB book) will provide the details.
  5. If session bean has container Managed Transaction and
       if there are these
        - Methods which use container Mangeded Entity Beans
        - JDBC which I suppose are not container managed
    If both of these are in a transaction, on failure only the container Managed method gets rolled back and not the JDBC.

    We need to use Bean Managed Transaction to include
    JDBC calls into the same transaction scope as methods using
    CMT - entity Beans.

    This is my view, Is there a different way.

  6. Won't the JDBC rollback automatically if a SQLException is occurs when the JDBC fails?
  7. The particular SQL that cause the SQLException will fail for sure, but let's say your have executed another SQL before it successfully, and you want both SQL's to succeed/fail at the same time, then you cannot rely on SQLException for TX management (never is a good idea).
  8. I don't think your assumption is correct. When EJBs are called as part of a single transaction and any method of these EJBs throws and exception, the whole transaction is rolled back. So, any SQL issued by your JDBC code is also rolled-back. Of course, I am assuming that all the beans set their transaction attributes in such a way that they could become part of the current transaction.
  9. Hi,
    1. I agree that when "EJBs are called as part of a single transaction and any method of these EJBs throws and exception, the whole transaction is rolled back of course with the assumption", How does a bunch of JDBC calls become
    part of the above single transaction to be rolled back succesfully.
    The EJBS have the transaction attribute to use current transaction but what about bunch of JDBC calls.

    I was not succesful in Rolling back simultaneously the EJBS
    and the bunch of JDBC calls in a sessions CMT. I plan to use
    BMT. Is there a way with CMT.
    2. Also since the discussion is going on about Transaction,
    In weblogic, EJBS in single transaction get rolled back only
    when RemoteException is thrown not when FinderException is it true!!

  10. There are two ways, that I am aware of, for container managed transactions to rollback back.
    1) You catch the JDBC exception (SQL Exception) and throw a system exception, for example, EJBException. Note that the EJBException descends from RuntimeException and therefore does not need to be declared in the throws clause. Actually any undeclared exception (which is basically a system exception) that gets thrown will cause the transaction to rollback. Try this by creating an empty ArrayList() and then do a get(10) on the ArrayList, this will force an ArrayIndex error and the transaction to rollback.
    2) OR you catch the exception and call setRollBackOnly() on the EJBContext. This will instruct the container to mark the transaction so that it never commits.

    The reason the rollback works across multiple JDBC calls is that the container keeps track of the connection it gave you and all the work you do on the connection is rolled back if case 1 or 2 happens. The container begins a transaction before the ejb method starts and commits it right before the method ends. The close method on the connection does not really close the connection, instead the connection is returned to the pool and given back to you if you make other JDBC calls within the same transaction.

  11. Hi,
        I have similar problem.
        I am using a session bean which has a method for deleting (first JDBC call) and inserting rows (Second JDBC call) in the database. I am throwing an application exception while inserting rows. From my client I am catching the aplication exception and throwing an EJB exception, Which should roll back my data, even deleting rows. But with the container transaction attribute "Required", I see the transaction rolled back on weblogic console, But my database updated till I throw Exception.
       How can I make all the JDBC calls are within my container transaction and rollback all my JDBC calls?

       By the way Iam not using the JDBC connection pool from weblogic.properties file. I am getting connection from an independent JAVA class. Is this has the effect on trasactions?

    Thanks in advance.