Exception Handling with TransactionUtil

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Exception Handling with TransactionUtil

Michael Imhof
I'm a little bit confused about the exception handling used with TransactionUtil.
Why is TransactionUtil.commit() always executed (its in the finally block)?

If you look at the code below (simplified code snippet of ByConditionFinder.runFind(..)) and
imagine a NullPointerException happens inside the //Some code place.
Because NullPointerException is not catched, the finally block will execute and the
Transaction will commit. Is this what we want?

      boolean beganTransaction = false;
      try {
         beganTransaction = TransactionUtil.begin();
          ..//Some code (every exception could occur here)
      } catch (GenericEntityException t) {                          
          TransactionUtil.rollback(beganTransaction, t.getMessage(), t);                    
      } finally {
          TransactionUtil.commit(beganTransaction);
      }

The transaction construct I'm used to (from other projects) is the following:

      boolean beganTransaction = false;
      try {
         beganTransaction = TransactionUtil.begin();
         ..//Some code (every exception could occur here)
         TransactionUtil.commit(beganTransaction);
      } catch (Throwable t) {                          
          TransactionUtil.rollback(beganTransaction, t.getMessage(), t);      
           if (t instanceof Error) {
              throw (Error)t;
           }              
      }

Michael
Reply | Threaded
Open this post in threaded view
|

Re: Exception Handling with TransactionUtil

David E Jones
The reason for this pattern is to make absolutely sure that we don't leave the method without closing (commit or rollback) the transaction.

What is inside the try catch is then responsible for handling errors, and if errors happen in code it calls there will typically be a rollback only flag set or the like.

In general this is safer. It isn't  perfect and of course you can write code to break it unless there is a general throwable catch block.

this stuff is as is because of real world bugs and problems. Are you asking about this because you found a problem, or just curious?

In general, yes, this is a best practice for transaction management.

-David


> ------- Original Message -------
> From: Michael Imhof <[hidden email]>
> To: [hidden email]
> Sent: 5/31/07, 5:54:22 AM
> Subject: Exception Handling with TransactionUtil
> I'm a little bit confused about the exception handling used with
> TransactionUtil.
> Why is TransactionUtil.commit() always executed (its in the finally block)?
>
> If you look at the code below (simplified code snippet of
> ByConditionFinder.runFind(..)) and
> imagine a NullPointerException happens inside the //Some code place.
> Because NullPointerException is not catched, the finally block will execute
> and the
> Transaction will commit. Is this what we want?
>
>       boolean beganTransaction = false;
>       try {
>          beganTransaction = TransactionUtil.begin();
>           ..//Some code (every exception could occur here)
>       } catch (GenericEntityException t) {                          
>           TransactionUtil.rollback(beganTransaction, t.getMessage(), t);                    
>       } finally {
>           TransactionUtil.commit(beganTransaction);
>       }
>
> The transaction construct I'm used to (from other projects) is the
> following:
>
>       boolean beganTransaction = false;
>       try {
>          beganTransaction = TransactionUtil.begin();
>          ..//Some code (every exception could occur here)
>          TransactionUtil.commit(beganTransaction);
>       } catch (Throwable t) {                          
>           TransactionUtil.rollback(beganTransaction, t.getMessage(), t);      
>            if (t instanceof Error) {
>               throw (Error)t;
>            }              
>       }
>
> Michael
> --
> View this message in context: http://www.nabble.com/Exception-Handling-with-TransactionUtil-tf3846106.html#a10892373
> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Exception Handling with TransactionUtil

Michael Imhof
I'm just curious. I try to understand what happens when any exception/ error occurs to make our ofbiz applications stable. And for this, I'm testing worst cases...

Even, if I don't have a specific problem, I think I will change all to catch(Throwable t) in
our local OfBiz copy...

Michael

PS: I'm using the following chart to understand the exception flow (excluding bsh and ftl's).


David E Jones wrote
The reason for this pattern is to make absolutely sure that we don't leave the method without closing (commit or rollback) the transaction.

What is inside the try catch is then responsible for handling errors, and if errors happen in code it calls there will typically be a rollback only flag set or the like.

In general this is safer. It isn't  perfect and of course you can write code to break it unless there is a general throwable catch block.

this stuff is as is because of real world bugs and problems. Are you asking about this because you found a problem, or just curious?

In general, yes, this is a best practice for transaction management.

-David


> ------- Original Message -------
> From: Michael Imhof <michael.imhof@nowhow.ch>
> To: dev@ofbiz.apache.org
> Sent: 5/31/07, 5:54:22 AM
> Subject: Exception Handling with TransactionUtil
> I'm a little bit confused about the exception handling used with
> TransactionUtil.
> Why is TransactionUtil.commit() always executed (its in the finally block)?
>
> If you look at the code below (simplified code snippet of
> ByConditionFinder.runFind(..)) and
> imagine a NullPointerException happens inside the //Some code place.
> Because NullPointerException is not catched, the finally block will execute
> and the
> Transaction will commit. Is this what we want?
>
>       boolean beganTransaction = false;
>       try {
>          beganTransaction = TransactionUtil.begin();
>           ..//Some code (every exception could occur here)
>       } catch (GenericEntityException t) {                          
>           TransactionUtil.rollback(beganTransaction, t.getMessage(), t);                    
>       } finally {
>           TransactionUtil.commit(beganTransaction);
>       }
>
> The transaction construct I'm used to (from other projects) is the
> following:
>
>       boolean beganTransaction = false;
>       try {
>          beganTransaction = TransactionUtil.begin();
>          ..//Some code (every exception could occur here)
>          TransactionUtil.commit(beganTransaction);
>       } catch (Throwable t) {                          
>           TransactionUtil.rollback(beganTransaction, t.getMessage(), t);      
>            if (t instanceof Error) {
>               throw (Error)t;
>            }              
>       }
>
> Michael
> --
> View this message in context: http://www.nabble.com/Exception-Handling-with-TransactionUtil-tf3846106.html#a10892373
> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>
>