6 Replies Latest reply on Jun 17, 2004 5:09 AM by Maik Lehradt

    No rollback of inserted data?

    Maik Lehradt Newbie

      Hi,

      I am relative new to EJB and need some help. Maybe you can give me some pointers.

      Consider this scenario:

      - Stateless Session Facade with transaction "Required"
      - Facade inserts CMP-EJB #1
      - Facade does something else and throws an exception
      - Transaction should (?!) roll back
      - Data of CMP-EJB #1 still in DB

      If I understand transactions correctly, the last should never happen since the transaction is rollbacked.

      Some more basic questions:
      1. If a method in a stateless session bean is set to Transaction "Required" and throws and exception, does it really rollback the current transaction?
      2. How can I assure that a transaction is rollbacked if the answer to 1. is "No"?
      3. If I modify an EJB and an transaction is thrown, will this modification be rollbacked?
      4. If the answer to 3. is "No", what the &%$ do transactions in EJBs really do?


      Regards,
      Maik

        • 1. Re: No rollback of inserted data?
          dannyyates Newbie

          Depends on the transaction settings of the Entity Bean, and, more importantly, on the type of exception being thrown. Read the EJB spec.

          • 2. Re: No rollback of inserted data?
            dannyyates Newbie

            Oh, and it also depends on whether your database supports transactions. I understand that certain configuration of MySQL, for example, don't. Not sure about Hypersonic.

            • 3. Re: No rollback of inserted data?
              gorano Newbie

              If you read the spec you will see that rollback on on only some exceptions make sense.

              One of the most important things to understand in J2EE development is transactions. If you want to
              force rollback you can always play with the
              setRollbackOnly() method.

              /G

              • 4. Re: No rollback of inserted data?
                Maik Lehradt Newbie

                Thanks all for your replies. After I read the EJB 2.0 specification, I can understand why the transaction is not rollbacked automatically (If everything else failed, read the documentation... ;)).

                I am nevertheless somewhat unsure how I should handle exceptions. I surrounded critical sections with try/catch blocks to catch all known Exceptions, including RuntimeExceptions (in the rare case of some bug into the code) to ensure a rollback in case of an error. My code works now and all transaction are rollbacked regardless which exceptions the EJB will throw. Is this the "right" way to handle exceptions?

                • 5. Re: No rollback of inserted data?
                  dannyyates Newbie

                  Java broadly divides exceptions into two types: checked and unchecked. Unchecked exceptions derive from RuntimeException or Error. Everything else is a checked exception. Checked exceptions are the ones that the compiler forces you to either catch or else declare with a throws clause in your method declaration.

                  The EJB spec talks about application and system exceptions. Broadly, EJB system exceptions are the same as Java unchecked exceptions, with the addition of anything deriving from java.rmi.RemoteException. That is, EJB system exceptions are RuntimeException, Error and RemoteException and their descendants.

                  RuntimeException and Error should never be generated by your code - they typically come from the JVM in response to critical, non-recoverable system problems (like, out of memory, etc.) RemoteException should also never be generated by your code - they are generated by the RMI runtime in response to comms (network) related problems.

                  Since you should never be generating any of these EJB system exceptions, (and most of them are unchecked anyway) it is unreasonable for the container to expect you to deal with them. Therefore, if any of these make their way out of your bean method, the container will catch them and roll back your transaction for you.

                  However, any EJB application exceptions (everything other than system exceptions) are checked. Therefore, the compiler will force you to catch them or explicitly rethrow them. Since you are forced into doing this, the container assumes that you have the power to decide whether to roll back the transaction or not. If you propogate these exceptions back up to the container, it will send them across the wire and they will appear on your client. This is good. However, the container doesn't know if the client is capable of retrying the operation, etc. Therefore it doesn't automatically roll back the transaction.

                  So... the compiler is your friend. If you always catch the exceptions it tells you to catch, then you will be in command of all EJB application exceptions. You can then decide what the correct action is. In my experience, the correct action is typically to roll back the transaction and then rethrow the exception so that the client is aware of it.

                  For a more thorough treatment of this subject, check out Monson-Haefel, Enterprise Java Beans (I have the 3rd edition which covers EJB2.0) published by O'Reilly. Chapter 14 deals with transactions, and the section 'Exceptions and Transactions' deals with exactly that, and very thoroughly. I highly recommend the table on pp439-441 (of the 3rd edition).

                  • 6. Re: No rollback of inserted data?
                    Maik Lehradt Newbie

                    Thanks, dannyyates. The book is surprisingly comprehensive :)